acidic_job 1.0.0.pre20 → 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: e608eefef4baffbfb2c95dcbef942a53c9ca242c4c593ddbbe0d677ef7d318da
4
- data.tar.gz: 65bed32739c1a1a860102e59dac69598c4357512034d8d3e87ed772469b9bac0
3
+ metadata.gz: f47391c0a8bdb8c62c967d716d0190eeddc5ebdd28af81309ffea17ae58f52b2
4
+ data.tar.gz: 575abae7eb9f70a81537b3260fa8a5ac76d64c231936f0f8e4d96b9e4be116d7
5
5
  SHA512:
6
- metadata.gz: 5a5f6155e20f929c631392f00480f57928455778e13117609457be9b8624e7f16c41661df96ae34a4045582f957b044cbdf811bfa7e187dd627b8b72b80edb90
7
- data.tar.gz: 6a663d288bd1ef3ba5cfac8e137fd496ebbca76e08573e50d706ed2570c98b6fe3148b8c9335b55313a091ccd0cc226e3b9023878dd418d400af33fd0280c1b4
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.pre20)
4
+ acidic_job (1.0.0.pre21)
5
5
  activerecord
6
6
  activesupport
7
7
  database_cleaner
data/README.md CHANGED
@@ -269,6 +269,25 @@ class RideCreateJob < ActiveJob::Base
269
269
  end
270
270
  ```
271
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
+
272
291
  ### Run Finished Callbacks
273
292
 
274
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.
@@ -285,7 +304,7 @@ class RideCreateJob < ActiveJob::Base
285
304
  @params = ride_params
286
305
 
287
306
  with_acidity providing: { ride: nil } do
288
- step :create_ride_and_audit_record, awaits: [SomeJob]
307
+ step :create_ride_and_audit_record, awaits: [SomeJob.with('argument_1', keyword: 'value')]
289
308
  step :create_stripe_charge, args: [1, 2, 3], kwargs: { some: 'thing' }
290
309
  step :send_receipt
291
310
  end
@@ -299,6 +318,8 @@ class RideCreateJob < ActiveJob::Base
299
318
  end
300
319
  ```
301
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
+
302
323
  ## Testing
303
324
 
304
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,27 +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,
21
+ {
22
+ "run_id" => run.id,
20
23
  "step_result_yaml" => step_result.to_yaml.strip,
21
24
  "parent_worker" => self.class.name,
22
- "job_names" => jobs.map(&:to_s) }
25
+ "job_names" => jobs.map { |job| job_name(job) }
26
+ }
23
27
  )
24
28
 
25
29
  # NOTE: The jobs method is atomic.
26
30
  # All jobs created in the block are actually pushed atomically at the end of the block.
27
31
  # If an error is raised, none of the jobs will go to Redis.
28
32
  step_batch.jobs do
29
- jobs.each do |worker_name|
30
- # TODO: handle Symbols as well
31
- worker = worker_name.is_a?(String) ? worker_name.constantize : worker_name
32
-
33
- if worker.instance_method(:perform).arity.presence_in [0, -1]
34
- worker.perform_async
35
- elsif worker.instance_method(:perform).arity == 1
36
- worker.perform_async(run.id)
37
- else
38
- raise TooManyParametersForParallelJob
39
- end
33
+ jobs.each do |job|
34
+ worker, args, kwargs = job_args_and_kwargs(job)
35
+
36
+ worker.perform_async(*args, **kwargs)
40
37
  end
41
38
  end
42
39
  end
@@ -53,5 +50,33 @@ module AcidicJob
53
50
  # when a batch of jobs for a step succeeds, we begin processing the `AcidicJob::Run` record again
54
51
  process_run(run)
55
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
56
81
  end
57
82
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- VERSION = "1.0.0.pre20"
4
+ VERSION = "1.0.0.pre21"
5
5
  end
data/lib/acidic_job.rb CHANGED
@@ -68,6 +68,10 @@ module AcidicJob
68
68
  super
69
69
  end
70
70
 
71
+ def with(*args, **kwargs)
72
+ new(*args, **kwargs)
73
+ end
74
+
71
75
  def acidic_identifier
72
76
  @acidic_identifier
73
77
  end
@@ -79,11 +83,11 @@ module AcidicJob
79
83
  @__acidic_job_args = args
80
84
  @__acidic_job_kwargs = kwargs
81
85
 
82
- if method(__method__).super_method.arity.zero?
83
- super()
84
- else
85
- super(*args, **kwargs)
86
- end
86
+ super(*args, **kwargs)
87
+ rescue ArgumentError => e
88
+ raise e unless e.message.include?("wrong number of arguments")
89
+
90
+ super()
87
91
  end
88
92
 
89
93
  def with_acidity(providing: {})
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.pre20
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-16 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