acidic_job 1.0.0.pre18 → 1.0.0.pre21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a350dbda056af9bf8965e6a68ece409285d0ba18c03c264509e7249e1635883
4
- data.tar.gz: 4361b820ca0efb3f30fbd726692ffbe815746d5adcf1582710e4abcee3246ca6
3
+ metadata.gz: f47391c0a8bdb8c62c967d716d0190eeddc5ebdd28af81309ffea17ae58f52b2
4
+ data.tar.gz: 575abae7eb9f70a81537b3260fa8a5ac76d64c231936f0f8e4d96b9e4be116d7
5
5
  SHA512:
6
- metadata.gz: e97d5c3dc34f74249d9aed1a43ac80a9db776cc7f9eb7e19894bbbbce9ccf4c74395f988fb9cf14d918bf8107642b948e018dfc407528523cd056ff596a86bb7
7
- data.tar.gz: ac977d26c7dd272ea9c7503846beeed90b909d52abd425b96c354ac0d21658dbe0849752d005e4b847749667bca6298557ae1edcd75a37278fb9db904875e23d
6
+ metadata.gz: 6d325fad1fb3240a6cf56d5b8d683b4bf4a0ab8b44c68173141d96fc7ca23a4c8d9f9fcf36d3410ed74f6dec9c16ef4739a642bb09e106050f1a21bc473e3a82
7
+ data.tar.gz: 355057c6f50d2b37a1b5837247d0d54b9e40e9fedc5793115a607bf9c03353e9ae5f847624608778ee54bdc1bfb950888c33b5ff6db96cb42f83001582571377
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- acidic_job (1.0.0.pre18)
4
+ acidic_job (1.0.0.pre21)
5
5
  activerecord
6
6
  activesupport
7
7
  database_cleaner
@@ -9,67 +9,67 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actioncable (7.0.2.3)
13
- actionpack (= 7.0.2.3)
14
- activesupport (= 7.0.2.3)
12
+ actioncable (7.0.3)
13
+ actionpack (= 7.0.3)
14
+ activesupport (= 7.0.3)
15
15
  nio4r (~> 2.0)
16
16
  websocket-driver (>= 0.6.1)
17
- actionmailbox (7.0.2.3)
18
- actionpack (= 7.0.2.3)
19
- activejob (= 7.0.2.3)
20
- activerecord (= 7.0.2.3)
21
- activestorage (= 7.0.2.3)
22
- activesupport (= 7.0.2.3)
17
+ actionmailbox (7.0.3)
18
+ actionpack (= 7.0.3)
19
+ activejob (= 7.0.3)
20
+ activerecord (= 7.0.3)
21
+ activestorage (= 7.0.3)
22
+ activesupport (= 7.0.3)
23
23
  mail (>= 2.7.1)
24
24
  net-imap
25
25
  net-pop
26
26
  net-smtp
27
- actionmailer (7.0.2.3)
28
- actionpack (= 7.0.2.3)
29
- actionview (= 7.0.2.3)
30
- activejob (= 7.0.2.3)
31
- activesupport (= 7.0.2.3)
27
+ actionmailer (7.0.3)
28
+ actionpack (= 7.0.3)
29
+ actionview (= 7.0.3)
30
+ activejob (= 7.0.3)
31
+ activesupport (= 7.0.3)
32
32
  mail (~> 2.5, >= 2.5.4)
33
33
  net-imap
34
34
  net-pop
35
35
  net-smtp
36
36
  rails-dom-testing (~> 2.0)
37
- actionpack (7.0.2.3)
38
- actionview (= 7.0.2.3)
39
- activesupport (= 7.0.2.3)
37
+ actionpack (7.0.3)
38
+ actionview (= 7.0.3)
39
+ activesupport (= 7.0.3)
40
40
  rack (~> 2.0, >= 2.2.0)
41
41
  rack-test (>= 0.6.3)
42
42
  rails-dom-testing (~> 2.0)
43
43
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
44
- actiontext (7.0.2.3)
45
- actionpack (= 7.0.2.3)
46
- activerecord (= 7.0.2.3)
47
- activestorage (= 7.0.2.3)
48
- activesupport (= 7.0.2.3)
44
+ actiontext (7.0.3)
45
+ actionpack (= 7.0.3)
46
+ activerecord (= 7.0.3)
47
+ activestorage (= 7.0.3)
48
+ activesupport (= 7.0.3)
49
49
  globalid (>= 0.6.0)
50
50
  nokogiri (>= 1.8.5)
51
- actionview (7.0.2.3)
52
- activesupport (= 7.0.2.3)
51
+ actionview (7.0.3)
52
+ activesupport (= 7.0.3)
53
53
  builder (~> 3.1)
54
54
  erubi (~> 1.4)
55
55
  rails-dom-testing (~> 2.0)
56
56
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
57
- activejob (7.0.2.3)
58
- activesupport (= 7.0.2.3)
57
+ activejob (7.0.3)
58
+ activesupport (= 7.0.3)
59
59
  globalid (>= 0.3.6)
60
- activemodel (7.0.2.3)
61
- activesupport (= 7.0.2.3)
62
- activerecord (7.0.2.3)
63
- activemodel (= 7.0.2.3)
64
- activesupport (= 7.0.2.3)
65
- activestorage (7.0.2.3)
66
- actionpack (= 7.0.2.3)
67
- activejob (= 7.0.2.3)
68
- activerecord (= 7.0.2.3)
69
- activesupport (= 7.0.2.3)
60
+ activemodel (7.0.3)
61
+ activesupport (= 7.0.3)
62
+ activerecord (7.0.3)
63
+ activemodel (= 7.0.3)
64
+ activesupport (= 7.0.3)
65
+ activestorage (7.0.3)
66
+ actionpack (= 7.0.3)
67
+ activejob (= 7.0.3)
68
+ activerecord (= 7.0.3)
69
+ activesupport (= 7.0.3)
70
70
  marcel (~> 1.0)
71
71
  mini_mime (>= 1.1.0)
72
- activesupport (7.0.2.3)
72
+ activesupport (7.0.3)
73
73
  concurrent-ruby (~> 1.0, >= 1.0.2)
74
74
  i18n (>= 1.6, < 2)
75
75
  minitest (>= 5.1)
@@ -82,7 +82,7 @@ GEM
82
82
  activesupport (>= 3.0.0)
83
83
  railties (>= 3.0.0)
84
84
  thor (>= 0.14.6)
85
- concurrent-ruby (1.1.9)
85
+ concurrent-ruby (1.1.10)
86
86
  connection_pool (2.2.5)
87
87
  crass (1.0.6)
88
88
  database_cleaner (2.0.1)
@@ -112,11 +112,10 @@ GEM
112
112
  http-form_data (2.3.0)
113
113
  i18n (1.10.0)
114
114
  concurrent-ruby (~> 1.0)
115
- io-wait (0.2.1)
116
115
  llhttp-ffi (0.4.0)
117
116
  ffi-compiler (~> 1.0)
118
117
  rake (~> 13.0)
119
- loofah (2.15.0)
118
+ loofah (2.18.0)
120
119
  crass (~> 1.0.2)
121
120
  nokogiri (>= 1.5.9)
122
121
  mail (2.7.1)
@@ -134,52 +133,51 @@ GEM
134
133
  digest
135
134
  net-protocol
136
135
  timeout
137
- net-protocol (0.1.2)
138
- io-wait
136
+ net-protocol (0.1.3)
139
137
  timeout
140
138
  net-smtp (0.3.1)
141
139
  digest
142
140
  net-protocol
143
141
  timeout
144
142
  nio4r (2.5.8)
145
- nokogiri (1.13.3)
143
+ nokogiri (1.13.6)
146
144
  mini_portile2 (~> 2.8.0)
147
145
  racc (~> 1.4)
148
- nokogiri (1.13.3-x86_64-darwin)
146
+ nokogiri (1.13.6-x86_64-darwin)
149
147
  racc (~> 1.4)
150
148
  noticed (1.5.9)
151
149
  http (>= 4.0.0)
152
150
  rails (>= 5.2.0)
153
- parallel (1.21.0)
154
- parser (3.1.1.0)
151
+ parallel (1.22.1)
152
+ parser (3.1.2.0)
155
153
  ast (~> 2.4.1)
156
- public_suffix (4.0.6)
154
+ public_suffix (4.0.7)
157
155
  racc (1.6.0)
158
156
  rack (2.2.3)
159
157
  rack-test (1.1.0)
160
158
  rack (>= 1.0, < 3)
161
- rails (7.0.2.3)
162
- actioncable (= 7.0.2.3)
163
- actionmailbox (= 7.0.2.3)
164
- actionmailer (= 7.0.2.3)
165
- actionpack (= 7.0.2.3)
166
- actiontext (= 7.0.2.3)
167
- actionview (= 7.0.2.3)
168
- activejob (= 7.0.2.3)
169
- activemodel (= 7.0.2.3)
170
- activerecord (= 7.0.2.3)
171
- activestorage (= 7.0.2.3)
172
- activesupport (= 7.0.2.3)
159
+ rails (7.0.3)
160
+ actioncable (= 7.0.3)
161
+ actionmailbox (= 7.0.3)
162
+ actionmailer (= 7.0.3)
163
+ actionpack (= 7.0.3)
164
+ actiontext (= 7.0.3)
165
+ actionview (= 7.0.3)
166
+ activejob (= 7.0.3)
167
+ activemodel (= 7.0.3)
168
+ activerecord (= 7.0.3)
169
+ activestorage (= 7.0.3)
170
+ activesupport (= 7.0.3)
173
171
  bundler (>= 1.15.0)
174
- railties (= 7.0.2.3)
172
+ railties (= 7.0.3)
175
173
  rails-dom-testing (2.0.3)
176
174
  activesupport (>= 4.2.0)
177
175
  nokogiri (>= 1.6)
178
176
  rails-html-sanitizer (1.4.2)
179
177
  loofah (~> 2.3)
180
- railties (7.0.2.3)
181
- actionpack (= 7.0.2.3)
182
- activesupport (= 7.0.2.3)
178
+ railties (7.0.3)
179
+ actionpack (= 7.0.3)
180
+ activesupport (= 7.0.3)
183
181
  method_source
184
182
  rake (>= 12.2)
185
183
  thor (~> 1.0)
@@ -187,20 +185,20 @@ GEM
187
185
  rainbow (3.1.1)
188
186
  rake (13.0.6)
189
187
  redis (4.6.0)
190
- regexp_parser (2.2.1)
188
+ regexp_parser (2.4.0)
191
189
  rexml (3.2.5)
192
- rubocop (1.26.0)
190
+ rubocop (1.29.1)
193
191
  parallel (~> 1.10)
194
192
  parser (>= 3.1.0.0)
195
193
  rainbow (>= 2.2.2, < 4.0)
196
194
  regexp_parser (>= 1.8, < 3.0)
197
- rexml
198
- rubocop-ast (>= 1.16.0, < 2.0)
195
+ rexml (>= 3.2.5, < 4.0)
196
+ rubocop-ast (>= 1.17.0, < 2.0)
199
197
  ruby-progressbar (~> 1.7)
200
198
  unicode-display_width (>= 1.4.0, < 3.0)
201
- rubocop-ast (1.16.0)
199
+ rubocop-ast (1.18.0)
202
200
  parser (>= 3.1.1.0)
203
- rubocop-minitest (0.18.0)
201
+ rubocop-minitest (0.19.1)
204
202
  rubocop (>= 0.90, < 2.0)
205
203
  rubocop-rake (0.6.0)
206
204
  rubocop (~> 1.0)
@@ -216,7 +214,7 @@ GEM
216
214
  simplecov-html (0.12.3)
217
215
  simplecov_json_formatter (0.1.4)
218
216
  sqlite3 (1.4.2)
219
- strscan (3.0.1)
217
+ strscan (3.0.3)
220
218
  thor (1.2.1)
221
219
  timeout (0.2.0)
222
220
  tzinfo (2.0.4)
data/README.md CHANGED
@@ -68,8 +68,10 @@ It provides a suite of functionality that empowers you to create complex, robust
68
68
  * Persisted Attributes — when retrying jobs at later steps, we need to ensure that data created in previous steps is still available to later steps on retry.
69
69
  * Transactionally Staged Jobs — enqueue additional jobs within the acidic transaction safely
70
70
  * Custom Idempotency Keys — use something other than the job ID for the idempotency key of the job run
71
+ * Iterable Steps — define steps that iterate over some collection fully until moving on to the next step
71
72
  * Sidekiq Callbacks — bring ActiveJob-like callbacks into your pure Sidekiq Workers
72
73
  * Sidekiq Batches — leverage the power of Sidekiq Pro's `batch` functionality without the hassle
74
+ * Run Finished Callbacks — set callbacks for when a job run finishes fully
73
75
 
74
76
  ### Transactional Steps
75
77
 
@@ -80,9 +82,10 @@ class RideCreateJob < ActiveJob::Base
80
82
  include AcidicJob
81
83
 
82
84
  def perform(user_id, ride_params)
83
- user = User.find(user_id)
85
+ @user = User.find(user_id)
86
+ @params = ride_params
84
87
 
85
- with_acidity providing: { user: user, params: ride_params, ride: nil } do
88
+ with_acidity providing: { ride: nil } do
86
89
  step :create_ride_and_audit_record
87
90
  step :create_stripe_charge
88
91
  step :send_receipt
@@ -128,7 +131,7 @@ class RideCreateJob < ActiveJob::Base
128
131
  end
129
132
 
130
133
  def create_stripe_charge
131
- Stripe::Charge.create(amount: 20_00, customer: self.ride.user)
134
+ Stripe::Charge.create(amount: 20_00, customer: @ride.user)
132
135
  end
133
136
 
134
137
  # ...
@@ -139,6 +142,8 @@ end
139
142
 
140
143
  **Note:** You will note the use of `self.ride = ...` in the code sample above. In order to call the attribute setter method that will sync with the database record, you _must_ use this style. `@ride = ...` and/or `ride = ...` will both fail to sync the value with the database record.
141
144
 
145
+ The default pattern you should follow when defining your `perform` method is to make any values that your `step` methods need access to, but are present at the start of the `perform` method simply instance variables. You only need to `provide` attributes that will be set _during a step_. This means, the initial value will almost always be `nil`.
146
+
142
147
  ### Transactionally Staged Jobs
143
148
 
144
149
  A standard problem when inside of database transactions is enqueuing other jobs. On the one hand, you could enqueue a job inside of a transaction that then rollbacks, which would leave that job to fail and retry and fail. On the other hand, you could enqueue a job that is picked up before the transaction commits, which would mean the records are not yet available to this job.
@@ -150,9 +155,10 @@ class RideCreateJob < ActiveJob::Base
150
155
  include AcidicJob
151
156
 
152
157
  def perform(user_id, ride_params)
153
- user = User.find(user_id)
158
+ @user = User.find(user_id)
159
+ @params = ride_params
154
160
 
155
- with_acidity providing: { user: user, params: ride_params, ride: nil } do
161
+ with_acidity providing: { ride: nil } do
156
162
  step :create_ride_and_audit_record
157
163
  step :create_stripe_charge
158
164
  step :send_receipt
@@ -211,6 +217,28 @@ end
211
217
 
212
218
  > **Note:** The signature of the `acidic_by` proc _needs to match the signature_ of the job's `perform` method.
213
219
 
220
+ ### Iterable Steps
221
+
222
+ Sometimes our workflows have steps that need to iterate over a collection and perform an action for each item in the collection before moving on to the next step in the workflow. In these cases, we can use the `for_each` option when defining our step to specific the collection, and `acidic_job` will pass each item into your step method for processing, keeping the same transactional guarantees as for any step. This means that if your step encounters an error in processing any item in the collection, when your job is retried, the job will jump right back to that step and right back to that item in the collection to try again.
223
+
224
+ ```ruby
225
+ class ExampleJob < ActiveJob::Base
226
+ include AcidicJob
227
+
228
+ def perform(record:)
229
+ with_acidity providing: { collection: [1, 2, 3, 4, 5] } do
230
+ step :process_item, for_each: :collection
231
+ step :next_step
232
+ end
233
+ end
234
+
235
+ def process_item(item)
236
+ # do whatever work needs to be done with this individual item
237
+ end
238
+ end
239
+ ```
240
+
241
+ **Note:** The same restrictions apply here as for any persisted attribute — you can only use objects that can be serialized by ActiveRecord.
214
242
 
215
243
  ### Sidekiq Callbacks
216
244
 
@@ -229,9 +257,10 @@ class RideCreateJob < ActiveJob::Base
229
257
  include AcidicJob
230
258
 
231
259
  def perform(user_id, ride_params)
232
- user = User.find(user_id)
260
+ @user = User.find(user_id)
261
+ @params = ride_params
233
262
 
234
- with_acidity providing: { user: user, params: ride_params, ride: nil } do
263
+ with_acidity providing: { ride: nil } do
235
264
  step :create_ride_and_audit_record, awaits: [SomeJob]
236
265
  step :create_stripe_charge, args: [1, 2, 3], kwargs: { some: 'thing' }
237
266
  step :send_receipt
@@ -240,6 +269,57 @@ class RideCreateJob < ActiveJob::Base
240
269
  end
241
270
  ```
242
271
 
272
+ If you need to await a job that takes arguments, you can prepare that job along with its arguments using the `with` class method that `acidic_job` will add to your jobs:
273
+
274
+ ```ruby
275
+ class RideCreateJob < ActiveJob::Base
276
+ include AcidicJob
277
+
278
+ def perform(user_id, ride_params)
279
+ @user = User.find(user_id)
280
+ @params = ride_params
281
+
282
+ with_acidity providing: { ride: nil } do
283
+ step :create_ride_and_audit_record, awaits: [SomeJob]
284
+ step :create_stripe_charge, args: [1, 2, 3], kwargs: { some: 'thing' }
285
+ step :send_receipt
286
+ end
287
+ end
288
+ end
289
+ ```
290
+
291
+ ### Run Finished Callbacks
292
+
293
+ When working with workflow jobs that make use of the `awaits` feature for a step, it is important to remember that the `after_perform` callback will be called _as soon as the first `awaits` step has enqueued job_, and **not** when the entire job run has finished. `acidic_job` allows the `perform` method to finish so that the queue for the workflow job is cleared to pick up new work while the `awaits` jobs are running. `acidic_job` will automatically re-enqueue the workflow job and progress to the next step when all of the `awaits` jobs have successfully finished. However, this means that `after_perform` **is not necessarily** the same as `after_finish`. In order to provide the opportunity for you to execute callback logic _if and only if_ a job run has finished, we provide callback hooks for the `finish` event.
294
+
295
+ For example, you could use this hook to immediately clean up the `AcidicJob::Run` database record whenever the workflow job finishes successfully like so:
296
+
297
+ ```ruby
298
+ class RideCreateJob < ActiveJob::Base
299
+ include AcidicJob
300
+ set_callback :finish, :after, :delete_run_record
301
+
302
+ def perform(user_id, ride_params)
303
+ @user = User.find(user_id)
304
+ @params = ride_params
305
+
306
+ with_acidity providing: { ride: nil } do
307
+ step :create_ride_and_audit_record, awaits: [SomeJob.with('argument_1', keyword: 'value')]
308
+ step :create_stripe_charge, args: [1, 2, 3], kwargs: { some: 'thing' }
309
+ step :send_receipt
310
+ end
311
+ end
312
+
313
+ def delete_run_record
314
+ return unless acidic_job_run.succeeded?
315
+
316
+ acidic_job_run.destroy!
317
+ end
318
+ end
319
+ ```
320
+
321
+ You can also await a batch of jobs by simply passing multiple jobs to the `awaits` array (e.g. `awaits: [SomeJob, AnotherJob.with('argument_1', keyword: 'value')]`). Your top level workflow job will only continue to the next step once all of the jobs in your `awaits` array have successfully finished.
322
+
243
323
  ## Testing
244
324
 
245
325
  When testing acidic jobs, you are likely to run into `ActiveRecord::TransactionIsolationError`s:
@@ -6,6 +6,8 @@ module AcidicJob
6
6
  module Awaiting
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ private
10
+
9
11
  def enqueue_step_parallel_jobs(jobs, run, step_result)
10
12
  # `batch` is available from Sidekiq::Pro
11
13
  raise SidekiqBatchRequired unless defined?(Sidekiq::Batch)
@@ -16,23 +18,22 @@ module AcidicJob
16
18
  :success,
17
19
  "#{self.class.name}#step_done",
18
20
  # NOTE: options are marshalled through JSON so use only basic types.
19
- { "run_id" => run.id,
20
- "step_result_yaml" => step_result.to_yaml.strip }
21
+ {
22
+ "run_id" => run.id,
23
+ "step_result_yaml" => step_result.to_yaml.strip,
24
+ "parent_worker" => self.class.name,
25
+ "job_names" => jobs.map { |job| job_name(job) }
26
+ }
21
27
  )
28
+
22
29
  # NOTE: The jobs method is atomic.
23
30
  # All jobs created in the block are actually pushed atomically at the end of the block.
24
31
  # If an error is raised, none of the jobs will go to Redis.
25
32
  step_batch.jobs do
26
- jobs.each do |worker_name|
27
- # TODO: handle Symbols as well
28
- worker = worker_name.is_a?(String) ? worker_name.constantize : worker_name
29
- if worker.instance_method(:perform).arity.zero?
30
- worker.perform_async
31
- elsif worker.instance_method(:perform).arity == 1
32
- worker.perform_async(run.id)
33
- else
34
- raise TooManyParametersForParallelJob
35
- end
33
+ jobs.each do |job|
34
+ worker, args, kwargs = job_args_and_kwargs(job)
35
+
36
+ worker.perform_async(*args, **kwargs)
36
37
  end
37
38
  end
38
39
  end
@@ -49,5 +50,33 @@ module AcidicJob
49
50
  # when a batch of jobs for a step succeeds, we begin processing the `AcidicJob::Run` record again
50
51
  process_run(run)
51
52
  end
53
+
54
+ def job_name(job)
55
+ case job
56
+ when Class, Symbol
57
+ job.to_s
58
+ when String
59
+ job
60
+ else
61
+ job.class.name
62
+ end
63
+ end
64
+
65
+ def job_args_and_kwargs(job)
66
+ case job
67
+ when Class
68
+ [job, [], {}]
69
+ when String
70
+ [job.constantize, [], {}]
71
+ when Symbol
72
+ [job.to_s.constantize, [], {}]
73
+ else
74
+ [
75
+ job.class,
76
+ job.instance_variable_get(:@__acidic_job_args),
77
+ job.instance_variable_get(:@__acidic_job_kwargs)
78
+ ]
79
+ end
80
+ end
52
81
  end
53
82
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- VERSION = "1.0.0.pre18"
4
+ VERSION = "1.0.0.pre21"
5
5
  end
data/lib/acidic_job.rb CHANGED
@@ -47,12 +47,15 @@ module AcidicJob
47
47
  raise UnknownJobAdapter
48
48
  end
49
49
 
50
+ # TODO: write test for a staged job that uses awaits
50
51
  klass.set_callback :perform, :after, :delete_staged_job_record, if: :was_staged_job?
52
+ klass.define_callbacks :finish
51
53
 
52
54
  klass.instance_variable_set(:@acidic_identifier, :job_id)
53
55
  klass.define_singleton_method(:acidic_by_job_id) { @acidic_identifier = :job_id }
54
56
  klass.define_singleton_method(:acidic_by_job_args) { @acidic_identifier = :job_args }
55
57
  klass.define_singleton_method(:acidic_by) { |proc| @acidic_identifier = proc }
58
+ klass.attr_reader(:acidic_job_run)
56
59
  end
57
60
 
58
61
  included do
@@ -65,6 +68,10 @@ module AcidicJob
65
68
  super
66
69
  end
67
70
 
71
+ def with(*args, **kwargs)
72
+ new(*args, **kwargs)
73
+ end
74
+
68
75
  def acidic_identifier
69
76
  @acidic_identifier
70
77
  end
@@ -76,11 +83,11 @@ module AcidicJob
76
83
  @__acidic_job_args = args
77
84
  @__acidic_job_kwargs = kwargs
78
85
 
79
- if method(__method__).super_method.arity.zero?
80
- super()
81
- else
82
- super(*args, **kwargs)
83
- end
86
+ super(*args, **kwargs)
87
+ rescue ArgumentError => e
88
+ raise e unless e.message.include?("wrong number of arguments")
89
+
90
+ super()
84
91
  end
85
92
 
86
93
  def with_acidity(providing: {})
@@ -94,10 +101,10 @@ module AcidicJob
94
101
  # convert the array of steps into a hash of recovery_points and next steps
95
102
  workflow = define_workflow(@__acidic_job_steps)
96
103
 
97
- @run = ensure_run_record(workflow, providing)
104
+ @acidic_job_run = ensure_run_record(workflow, providing)
98
105
 
99
106
  # begin the workflow
100
- process_run(@run)
107
+ process_run(@acidic_job_run)
101
108
  end
102
109
 
103
110
  # DEPRECATED
@@ -128,7 +135,7 @@ module AcidicJob
128
135
 
129
136
  def process_run(run)
130
137
  # if the run record is already marked as finished, immediately return its result
131
- return run.succeeded? if run.finished?
138
+ return finish_run(run) if run.finished?
132
139
 
133
140
  # otherwise, we will enter a loop to process each step of the workflow
134
141
  loop do
@@ -167,7 +174,13 @@ module AcidicJob
167
174
  end
168
175
 
169
176
  # the loop will break once the job is finished, so simply report the status
170
- run.succeeded?
177
+ finish_run(run)
178
+ end
179
+
180
+ def finish_run(run)
181
+ run_callbacks :finish do
182
+ run.succeeded?
183
+ end
171
184
  end
172
185
 
173
186
  def step(method_name, awaits: [], for_each: nil)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acidic_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre18
4
+ version: 1.0.0.pre21
5
5
  platform: ruby
6
6
  authors:
7
7
  - fractaledmind
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-15 00:00:00.000000000 Z
11
+ date: 2022-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord