Class: Jidoka::Worker
- Inherits:
-
Object
- Object
- Jidoka::Worker
- Includes:
- ActiveSupport::Rescuable
- Defined in:
- lib/jidoka/worker.rb
Direct Known Subclasses
Constant Summary collapse
- BASE_ERRORS =
Shared error messages available to all Workers
{ invalid_state_transition: 'You cannot transition to this state', action_already_performed: 'This action has already been performed' }.freeze
- ERRORS =
Default ERRORS hash to be overridden by subclasses
{}.freeze
Instance Attribute Summary collapse
-
#error ⇒ String
readonly
Error message to display to end users.
-
#message ⇒ String
readonly
Error message to display to end users.
Class Method Summary collapse
- .dry_run(opts = {}) ⇒ Object
- .dry_run!(opts = {}) ⇒ Object
-
.enforce_arguments!(obj) ⇒ Object
– Class Methods –.
- .include_notify?(opts) ⇒ Boolean
- .initialize_and_call!(opts, *methods_to_call) ⇒ Object
- .possible_errors(with_prefix = false) ⇒ Object
- .run(opts = {}) ⇒ Object
- .run!(opts = {}) ⇒ Object
- .undo(opts = {}) ⇒ Object
- .undo!(opts = {}) ⇒ Object
Instance Method Summary collapse
- #_notify(**_opts) ⇒ Object
- #down ⇒ Object
- #failed {|_self| ... } ⇒ Object
-
#failure? ⇒ Boolean
– State Helpers –.
-
#initialize(args = nil) ⇒ Worker
constructor
– Instance Methods –.
- #notify! ⇒ Object
- #perform(opts = {}) ⇒ Object
- #prepare(opts) ⇒ Object
- #run ⇒ Object
- #run! ⇒ Object
- #success {|_self| ... } ⇒ Object
- #success? ⇒ Boolean
- #undo ⇒ Object
- #undo! ⇒ Object
- #up(_opts = nil) ⇒ Object
- #validate ⇒ Object
- #validate! ⇒ Object
-
#with_transaction(&block) ⇒ Object
Wraps ‘up` (and `down`) in an ActiveRecord transaction.
Constructor Details
#initialize(args = nil) ⇒ Worker
– Instance Methods –
73 74 75 76 77 78 |
# File 'lib/jidoka/worker.rb', line 73 def initialize(args = nil) super # Handle ActiveJob vs direct instantiation args @opts = args || (arguments ? arguments[0] : {}) @opts = @opts.transform_keys(&:to_sym) if @opts end |
Instance Attribute Details
#error ⇒ String (readonly)
Returns Error message to display to end users.
6 7 8 |
# File 'lib/jidoka/worker.rb', line 6 def error @error end |
#message ⇒ String (readonly)
Returns Error message to display to end users.
6 7 8 |
# File 'lib/jidoka/worker.rb', line 6 def @message end |
Class Method Details
.dry_run(opts = {}) ⇒ Object
44 45 46 |
# File 'lib/jidoka/worker.rb', line 44 def self.dry_run(opts = {}) initialize_and_call!(opts, :validate) end |
.dry_run!(opts = {}) ⇒ Object
40 41 42 |
# File 'lib/jidoka/worker.rb', line 40 def self.dry_run!(opts = {}) initialize_and_call!(opts, :validate!) end |
.enforce_arguments!(obj) ⇒ Object
– Class Methods –
21 22 23 |
# File 'lib/jidoka/worker.rb', line 21 def self.enforce_arguments!(obj) self.argument_types = obj.freeze end |
.include_notify?(opts) ⇒ Boolean
58 59 60 |
# File 'lib/jidoka/worker.rb', line 58 def self.include_notify?(opts) [nil, true].include?(opts.delete(:notify)) ? %i[notify!] : [] end |
.initialize_and_call!(opts, *methods_to_call) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/jidoka/worker.rb', line 62 def self.initialize_and_call!(opts, *methods_to_call) instance = new(opts.transform_keys(&:to_sym)) methods_to_call.each do |m| instance.send(m) break if instance.failure? end instance end |
.possible_errors(with_prefix = false) ⇒ Object
25 26 27 28 |
# File 'lib/jidoka/worker.rb', line 25 def self.possible_errors(with_prefix = false) @possible_errors ||= self::ERRORS with_prefix ? @possible_errors.transform_keys { |k| [to_s.underscore, k].join('-') } : @possible_errors end |
.run(opts = {}) ⇒ Object
34 35 36 37 38 |
# File 'lib/jidoka/worker.rb', line 34 def self.run(opts = {}) initialize_and_call!(opts, :validate, :run, *include_notify?(opts)).tap do |result| yield(result) if block_given? end end |
.run!(opts = {}) ⇒ Object
30 31 32 |
# File 'lib/jidoka/worker.rb', line 30 def self.run!(opts = {}) initialize_and_call!(opts, :validate!, :run!, *include_notify?(opts)) end |
.undo(opts = {}) ⇒ Object
52 53 54 55 56 |
# File 'lib/jidoka/worker.rb', line 52 def self.undo(opts = {}) initialize_and_call!(opts, :undo).tap do |result| yield(result) if block_given? end end |
.undo!(opts = {}) ⇒ Object
48 49 50 |
# File 'lib/jidoka/worker.rb', line 48 def self.undo!(opts = {}) initialize_and_call!(opts, :undo!) end |
Instance Method Details
#_notify(**_opts) ⇒ Object
161 |
# File 'lib/jidoka/worker.rb', line 161 def _notify(**_opts); end |
#down ⇒ Object
151 |
# File 'lib/jidoka/worker.rb', line 151 def down; end |
#failed {|_self| ... } ⇒ Object
173 174 175 |
# File 'lib/jidoka/worker.rb', line 173 def failed yield(self) if failure? end |
#failure? ⇒ Boolean
– State Helpers –
165 166 167 |
# File 'lib/jidoka/worker.rb', line 165 def failure? @failure.present? end |
#notify! ⇒ Object
153 154 155 156 157 158 159 |
# File 'lib/jidoka/worker.rb', line 153 def notify! _notify(**@opts) rescue StandardError => e report_error(e) # We do not re-raise notification errors by default unless in test raise(e) if defined?(Rails) && Rails.env.test? end |
#perform(opts = {}) ⇒ Object
80 81 82 83 84 85 |
# File 'lib/jidoka/worker.rb', line 80 def perform(opts = {}) @opts = opts.transform_keys(&:to_sym) validate! run! notify! end |
#prepare(opts) ⇒ Object
87 |
# File 'lib/jidoka/worker.rb', line 87 def prepare(opts); end |
#run ⇒ Object
111 112 113 114 115 |
# File 'lib/jidoka/worker.rb', line 111 def run run! rescue StandardError => e notice_failure!(e) end |
#run! ⇒ Object
104 105 106 107 108 109 |
# File 'lib/jidoka/worker.rb', line 104 def run! with_transaction { up(**@opts) } rescue Jidoka::ConditionNotMet, Jidoka::Failure => e notice_failure!(e) raise(e) end |
#success {|_self| ... } ⇒ Object
177 178 179 |
# File 'lib/jidoka/worker.rb', line 177 def success yield(self) if success? end |
#success? ⇒ Boolean
169 170 171 |
# File 'lib/jidoka/worker.rb', line 169 def success? !failure? end |
#undo ⇒ Object
125 126 127 128 129 |
# File 'lib/jidoka/worker.rb', line 125 def undo undo! rescue StandardError => e notice_failure!(e) end |
#undo! ⇒ Object
117 118 119 120 121 122 123 |
# File 'lib/jidoka/worker.rb', line 117 def undo! prepare_inverse(**@opts) if respond_to?(:prepare_inverse) with_transaction { down } rescue Jidoka::ConditionNotMet, Jidoka::Failure => e notice_failure!(e) raise(e) end |
#up(_opts = nil) ⇒ Object
147 148 149 |
# File 'lib/jidoka/worker.rb', line 147 def up(_opts = nil) raise NotImplementedError end |
#validate ⇒ Object
98 99 100 101 102 |
# File 'lib/jidoka/worker.rb', line 98 def validate validate! rescue StandardError => e notice_failure!(e) end |
#validate! ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/jidoka/worker.rb', line 89 def validate! validate_arguments!(**@opts) prepare(**@opts) validate_conditions!(**@opts) rescue Jidoka::ConditionNotMet, Jidoka::ArgumentClassMismatch, Jidoka::Failure => e notice_failure!(e) raise(e) end |
#with_transaction(&block) ⇒ Object
Wraps ‘up` (and `down`) in an ActiveRecord transaction. Override in a subclass to opt out — for example, when the work crosses non-transactional boundaries (external APIs, long-running processes) and holding a DB transaction open would be inappropriate:
class SyncSubscriber < Jidoka::Worker
def with_transaction
yield
end
def up(...); end
end
143 144 145 |
# File 'lib/jidoka/worker.rb', line 143 def with_transaction(&block) ActiveRecord::Base.transaction(&block) end |