acidic_job 1.0.0.pre29 → 1.0.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.codacy.yml +4 -0
  3. data/.github/FUNDING.yml +13 -0
  4. data/.github/workflows/main.yml +12 -15
  5. data/.gitignore +3 -1
  6. data/.rubocop.yml +50 -5
  7. data/.ruby-version +1 -0
  8. data/Gemfile.lock +134 -193
  9. data/README.md +164 -246
  10. data/TODO +77 -0
  11. data/acidic_job.gemspec +10 -10
  12. data/app/models/acidic_job/entry.rb +19 -0
  13. data/app/models/acidic_job/execution.rb +50 -0
  14. data/app/models/acidic_job/record.rb +11 -0
  15. data/app/models/acidic_job/value.rb +7 -0
  16. data/bin/console +5 -2
  17. data/bin/test_all +26 -0
  18. data/gemfiles/rails_7.0.gemfile +4 -1
  19. data/gemfiles/rails_7.1.gemfile +11 -0
  20. data/gemfiles/rails_7.2.gemfile +11 -0
  21. data/gemfiles/rails_8.0.gemfile +11 -0
  22. data/lib/acidic_job/arguments.rb +31 -0
  23. data/lib/acidic_job/builder.rb +29 -0
  24. data/lib/acidic_job/context.rb +46 -0
  25. data/lib/acidic_job/engine.rb +46 -0
  26. data/lib/acidic_job/errors.rb +87 -12
  27. data/lib/acidic_job/log_subscriber.rb +50 -0
  28. data/lib/acidic_job/serializers/exception_serializer.rb +31 -0
  29. data/lib/acidic_job/serializers/job_serializer.rb +27 -0
  30. data/lib/acidic_job/serializers/new_record_serializer.rb +25 -0
  31. data/lib/acidic_job/serializers/range_serializer.rb +28 -0
  32. data/lib/acidic_job/testing.rb +8 -12
  33. data/lib/acidic_job/version.rb +1 -1
  34. data/lib/acidic_job/workflow.rb +182 -0
  35. data/lib/acidic_job.rb +15 -284
  36. data/lib/generators/acidic_job/install_generator.rb +3 -3
  37. data/lib/generators/acidic_job/templates/create_acidic_job_tables_migration.rb.erb +33 -0
  38. metadata +51 -95
  39. data/.ruby_version +0 -1
  40. data/.tool-versions +0 -1
  41. data/gemfiles/rails_6.1.gemfile +0 -8
  42. data/lib/acidic_job/awaiting.rb +0 -102
  43. data/lib/acidic_job/extensions/action_mailer.rb +0 -29
  44. data/lib/acidic_job/extensions/active_job.rb +0 -40
  45. data/lib/acidic_job/extensions/noticed.rb +0 -54
  46. data/lib/acidic_job/extensions/sidekiq.rb +0 -111
  47. data/lib/acidic_job/finished_point.rb +0 -16
  48. data/lib/acidic_job/idempotency_key.rb +0 -82
  49. data/lib/acidic_job/perform_wrapper.rb +0 -22
  50. data/lib/acidic_job/recovery_point.rb +0 -18
  51. data/lib/acidic_job/rspec_configuration.rb +0 -31
  52. data/lib/acidic_job/run.rb +0 -100
  53. data/lib/acidic_job/serializer.rb +0 -163
  54. data/lib/acidic_job/staging.rb +0 -38
  55. data/lib/acidic_job/step.rb +0 -104
  56. data/lib/acidic_job/test_case.rb +0 -9
  57. data/lib/acidic_job/upgrade_service.rb +0 -118
  58. data/lib/generators/acidic_job/drop_tables_generator.rb +0 -26
  59. data/lib/generators/acidic_job/templates/create_acidic_job_runs_migration.rb.erb +0 -19
  60. data/lib/generators/acidic_job/templates/drop_acidic_job_keys_migration.rb.erb +0 -27
metadata CHANGED
@@ -1,101 +1,100 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acidic_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre29
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - fractaledmind
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-08-03 00:00:00.000000000 Z
10
+ date: 2025-05-14 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: activerecord
13
+ name: json
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '0'
18
+ version: 2.7.0
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '0'
25
+ version: 2.7.0
27
26
  - !ruby/object:Gem::Dependency
28
- name: activesupport
27
+ name: activejob
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '0'
32
+ version: '7.1'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '0'
39
+ version: '7.1'
41
40
  - !ruby/object:Gem::Dependency
42
- name: database_cleaner
41
+ name: activerecord
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: '0'
46
+ version: '7.1'
48
47
  type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
- version: '0'
53
+ version: '7.1'
55
54
  - !ruby/object:Gem::Dependency
56
- name: activejob
55
+ name: activesupport
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
58
  - - ">="
60
59
  - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
60
+ version: '7.1'
61
+ type: :runtime
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - ">="
67
66
  - !ruby/object:Gem::Version
68
- version: '0'
67
+ version: '7.1'
69
68
  - !ruby/object:Gem::Dependency
70
- name: combustion
69
+ name: railties
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
72
  - - ">="
74
73
  - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
74
+ version: '7.1'
75
+ type: :runtime
77
76
  prerelease: false
78
77
  version_requirements: !ruby/object:Gem::Requirement
79
78
  requirements:
80
79
  - - ">="
81
80
  - !ruby/object:Gem::Version
82
- version: '0'
81
+ version: '7.1'
83
82
  - !ruby/object:Gem::Dependency
84
- name: minitest
83
+ name: actionmailer
85
84
  requirement: !ruby/object:Gem::Requirement
86
85
  requirements:
87
86
  - - ">="
88
87
  - !ruby/object:Gem::Version
89
- version: '0'
88
+ version: '7.1'
90
89
  type: :development
91
90
  prerelease: false
92
91
  version_requirements: !ruby/object:Gem::Requirement
93
92
  requirements:
94
93
  - - ">="
95
94
  - !ruby/object:Gem::Version
96
- version: '0'
95
+ version: '7.1'
97
96
  - !ruby/object:Gem::Dependency
98
- name: net-smtp
97
+ name: chaotic_job
99
98
  requirement: !ruby/object:Gem::Requirement
100
99
  requirements:
101
100
  - - ">="
@@ -109,7 +108,7 @@ dependencies:
109
108
  - !ruby/object:Gem::Version
110
109
  version: '0'
111
110
  - !ruby/object:Gem::Dependency
112
- name: noticed
111
+ name: combustion
113
112
  requirement: !ruby/object:Gem::Requirement
114
113
  requirements:
115
114
  - - ">="
@@ -123,21 +122,7 @@ dependencies:
123
122
  - !ruby/object:Gem::Version
124
123
  version: '0'
125
124
  - !ruby/object:Gem::Dependency
126
- name: psych
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">"
130
- - !ruby/object:Gem::Version
131
- version: '4.0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">"
137
- - !ruby/object:Gem::Version
138
- version: '4.0'
139
- - !ruby/object:Gem::Dependency
140
- name: railties
125
+ name: minitest
141
126
  requirement: !ruby/object:Gem::Requirement
142
127
  requirements:
143
128
  - - ">="
@@ -206,20 +191,6 @@ dependencies:
206
191
  - - ">="
207
192
  - !ruby/object:Gem::Version
208
193
  version: '0'
209
- - !ruby/object:Gem::Dependency
210
- name: sidekiq
211
- requirement: !ruby/object:Gem::Requirement
212
- requirements:
213
- - - ">="
214
- - !ruby/object:Gem::Version
215
- version: '0'
216
- type: :development
217
- prerelease: false
218
- version_requirements: !ruby/object:Gem::Requirement
219
- requirements:
220
- - - ">="
221
- - !ruby/object:Gem::Version
222
- version: '0'
223
194
  - !ruby/object:Gem::Dependency
224
195
  name: simplecov
225
196
  requirement: !ruby/object:Gem::Requirement
@@ -248,20 +219,6 @@ dependencies:
248
219
  - - ">="
249
220
  - !ruby/object:Gem::Version
250
221
  version: '0'
251
- - !ruby/object:Gem::Dependency
252
- name: warning
253
- requirement: !ruby/object:Gem::Requirement
254
- requirements:
255
- - - ">="
256
- - !ruby/object:Gem::Version
257
- version: '0'
258
- type: :development
259
- prerelease: false
260
- version_requirements: !ruby/object:Gem::Requirement
261
- requirements:
262
- - - ">="
263
- - !ruby/object:Gem::Version
264
- version: '0'
265
222
  description: Idempotent operations for Rails apps, built on top of ActiveJob.
266
223
  email:
267
224
  - stephen.margheim@gmail.com
@@ -269,48 +226,49 @@ executables: []
269
226
  extensions: []
270
227
  extra_rdoc_files: []
271
228
  files:
229
+ - ".codacy.yml"
230
+ - ".github/FUNDING.yml"
272
231
  - ".github/workflows/main.yml"
273
232
  - ".gitignore"
274
233
  - ".rubocop.yml"
275
- - ".ruby_version"
276
- - ".tool-versions"
234
+ - ".ruby-version"
277
235
  - Gemfile
278
236
  - Gemfile.lock
279
237
  - LICENSE
280
238
  - README.md
281
239
  - Rakefile
240
+ - TODO
282
241
  - UPGRADE_GUIDE.md
283
242
  - acidic_job.gemspec
243
+ - app/models/acidic_job/entry.rb
244
+ - app/models/acidic_job/execution.rb
245
+ - app/models/acidic_job/record.rb
246
+ - app/models/acidic_job/value.rb
284
247
  - bin/console
285
248
  - bin/setup
249
+ - bin/test_all
286
250
  - blog_post.md
287
251
  - combustion/log/test.log
288
- - gemfiles/rails_6.1.gemfile
289
252
  - gemfiles/rails_7.0.gemfile
253
+ - gemfiles/rails_7.1.gemfile
254
+ - gemfiles/rails_7.2.gemfile
255
+ - gemfiles/rails_8.0.gemfile
290
256
  - lib/acidic_job.rb
291
- - lib/acidic_job/awaiting.rb
257
+ - lib/acidic_job/arguments.rb
258
+ - lib/acidic_job/builder.rb
259
+ - lib/acidic_job/context.rb
260
+ - lib/acidic_job/engine.rb
292
261
  - lib/acidic_job/errors.rb
293
- - lib/acidic_job/extensions/action_mailer.rb
294
- - lib/acidic_job/extensions/active_job.rb
295
- - lib/acidic_job/extensions/noticed.rb
296
- - lib/acidic_job/extensions/sidekiq.rb
297
- - lib/acidic_job/finished_point.rb
298
- - lib/acidic_job/idempotency_key.rb
299
- - lib/acidic_job/perform_wrapper.rb
300
- - lib/acidic_job/recovery_point.rb
301
- - lib/acidic_job/rspec_configuration.rb
302
- - lib/acidic_job/run.rb
303
- - lib/acidic_job/serializer.rb
304
- - lib/acidic_job/staging.rb
305
- - lib/acidic_job/step.rb
306
- - lib/acidic_job/test_case.rb
262
+ - lib/acidic_job/log_subscriber.rb
263
+ - lib/acidic_job/serializers/exception_serializer.rb
264
+ - lib/acidic_job/serializers/job_serializer.rb
265
+ - lib/acidic_job/serializers/new_record_serializer.rb
266
+ - lib/acidic_job/serializers/range_serializer.rb
307
267
  - lib/acidic_job/testing.rb
308
- - lib/acidic_job/upgrade_service.rb
309
268
  - lib/acidic_job/version.rb
310
- - lib/generators/acidic_job/drop_tables_generator.rb
269
+ - lib/acidic_job/workflow.rb
311
270
  - lib/generators/acidic_job/install_generator.rb
312
- - lib/generators/acidic_job/templates/create_acidic_job_runs_migration.rb.erb
313
- - lib/generators/acidic_job/templates/drop_acidic_job_keys_migration.rb.erb
271
+ - lib/generators/acidic_job/templates/create_acidic_job_tables_migration.rb.erb
314
272
  homepage: https://github.com/fractaledmind/acidic_job
315
273
  licenses:
316
274
  - MIT
@@ -319,7 +277,6 @@ metadata:
319
277
  source_code_uri: https://github.com/fractaledmind/acidic_job
320
278
  changelog_uri: https://github.com/fractaledmind/acidic_job/CHANGELOG.md
321
279
  rubygems_mfa_required: 'true'
322
- post_install_message:
323
280
  rdoc_options: []
324
281
  require_paths:
325
282
  - lib
@@ -330,12 +287,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
330
287
  version: 2.7.0
331
288
  required_rubygems_version: !ruby/object:Gem::Requirement
332
289
  requirements:
333
- - - ">"
290
+ - - ">="
334
291
  - !ruby/object:Gem::Version
335
- version: 1.3.1
292
+ version: '0'
336
293
  requirements: []
337
- rubygems_version: 3.3.7
338
- signing_key:
294
+ rubygems_version: 3.6.3
339
295
  specification_version: 4
340
296
  summary: Idempotent operations for Rails apps, built on top of ActiveJob.
341
297
  test_files: []
data/.ruby_version DELETED
@@ -1 +0,0 @@
1
- 2.7.1
data/.tool-versions DELETED
@@ -1 +0,0 @@
1
- ruby 3.1.1
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activemodel", "~> 6.1.0"
6
- gem "railties", "~> 6.1.0"
7
-
8
- gemspec path: "../"
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/concern"
4
-
5
- module AcidicJob
6
- module Awaiting
7
- extend ActiveSupport::Concern
8
-
9
- private
10
-
11
- def was_awaited_job?
12
- (acidic_job_run.present? && acidic_job_run.awaited_by.present?) ||
13
- (staged_job_run.present? && staged_job_run.awaited_by.present?)
14
- end
15
-
16
- def reenqueue_awaited_by_job
17
- run = staged_job_run&.awaited_by || acidic_job_run&.awaited_by
18
-
19
- return unless run
20
- return if run.batched_runs.outstanding.any?
21
-
22
- current_step = run.workflow[run.recovery_point.to_s]
23
- step_result = run.returning_to
24
-
25
- job = run.job_class.constantize.deserialize(run.serialized_job)
26
- # this needs to be explicitly set so that `was_workflow_job?` appropriately returns `true`
27
- # which is what the `after_finish :reenqueue_awaited_by_job` check needs
28
- job.instance_variable_set(:@acidic_job_run, run)
29
-
30
- # can't reproduce yet, but saw a bug in production where
31
- # nested awaits workflows had an unsaved `workflow` attribute
32
- run.save! if run.has_changes_to_save?
33
-
34
- step = Step.new(current_step, run, job, step_result)
35
- # TODO: WRITE REGRESSION TESTS FOR PARALLEL JOB FAILING AND RETRYING THE ORIGINAL STEP
36
- step.progress
37
-
38
- return if run.finished?
39
-
40
- # when a batch of jobs for a step succeeds, we begin processing the `AcidicJob::Run` record again
41
- # process_run(run)
42
- run.update_column(:locked_at, nil)
43
- job.enqueue
44
- end
45
-
46
- def enqueue_step_parallel_jobs(jobs_or_jobs_getter, run, step_result)
47
- awaited_jobs = case jobs_or_jobs_getter
48
- when Array
49
- jobs_or_jobs_getter
50
- when Symbol, String
51
- method(jobs_or_jobs_getter).call
52
- end
53
-
54
- AcidicJob::Run.transaction do
55
- awaited_jobs.compact.each do |awaited_job|
56
- worker_class, args, kwargs = job_args_and_kwargs(awaited_job)
57
-
58
- job = worker_class.new(*args, **kwargs)
59
-
60
- AcidicJob::Run.create!(
61
- staged: true,
62
- awaited_by: run,
63
- job_class: worker_class,
64
- serialized_job: job.serialize_job(*args, **kwargs),
65
- idempotency_key: job.idempotency_key
66
- )
67
- run.update(returning_to: step_result)
68
- end
69
- end
70
- end
71
-
72
- def step_done(_status, options)
73
- run = Run.find(options["run_id"])
74
- current_step = run.workflow[run.recovery_point.to_s]
75
- # re-hydrate the `step_result` object
76
- step_result = YAML.safe_load(options["step_result_yaml"], permitted_classes: [RecoveryPoint, FinishedPoint])
77
- step = Step.new(current_step, run, self, step_result)
78
-
79
- # TODO: WRITE REGRESSION TESTS FOR PARALLEL JOB FAILING AND RETRYING THE ORIGINAL STEP
80
- step.progress
81
- # when a batch of jobs for a step succeeds, we begin processing the `AcidicJob::Run` record again
82
- process_run(run)
83
- end
84
-
85
- def job_args_and_kwargs(job)
86
- case job
87
- when Class
88
- [job, [], {}]
89
- when String
90
- [job.constantize, [], {}]
91
- when Symbol
92
- [job.to_s.constantize, [], {}]
93
- else
94
- [
95
- job.class,
96
- job.instance_variable_get(:@__acidic_job_args),
97
- job.instance_variable_get(:@__acidic_job_kwargs)
98
- ]
99
- end
100
- end
101
- end
102
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/concern"
4
-
5
- module AcidicJob
6
- module Extensions
7
- module ActionMailer
8
- extend ActiveSupport::Concern
9
-
10
- def deliver_acidicly(_options = {})
11
- job_class = ::ActionMailer::MailDeliveryJob
12
-
13
- job_args = [@mailer_class.name, @action.to_s, "deliver_now", @params, *@args]
14
- # for Sidekiq, this depends on the Sidekiq::Serialization extension
15
- serialized_job = job_class.new(job_args).serialize
16
- acidic_identifier = job_class.respond_to?(:acidic_identifier) ? job_class.acidic_identifier : :job_id
17
- key = IdempotencyKey.new(acidic_identifier).value_for(serialized_job)
18
-
19
- AcidicJob::Run.create!(
20
- staged: true,
21
- job_class: job_class.name,
22
- serialized_job: serialized_job,
23
- idempotency_key: key
24
- )
25
- end
26
- alias deliver_transactionally deliver_acidicly
27
- end
28
- end
29
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/concern"
4
-
5
- module AcidicJob
6
- module Extensions
7
- module ActiveJob
8
- extend ActiveSupport::Concern
9
-
10
- concerning :Serialization do
11
- class_methods do
12
- def serialize_with_arguments(*args, **kwargs)
13
- job_or_instantiate(*args, **kwargs).serialize
14
- end
15
- end
16
-
17
- def serialize_job(*_args, **_kwargs)
18
- serialize
19
- end
20
- end
21
-
22
- class_methods do
23
- def perform_acidicly(*args, **kwargs)
24
- raise UnsupportedExtension unless defined?(::ActiveJob) && self < ::ActiveJob::Base
25
-
26
- serialized_job = serialize_with_arguments(*args, **kwargs)
27
- key = IdempotencyKey.new(acidic_identifier).value_for(serialized_job)
28
-
29
- AcidicJob::Run.create!(
30
- staged: true,
31
- job_class: name,
32
- serialized_job: serialized_job,
33
- idempotency_key: key
34
- )
35
- end
36
- alias_method :perform_transactionally, :perform_acidicly
37
- end
38
- end
39
- end
40
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AcidicJob
4
- module Extensions
5
- module Noticed
6
- extend ActiveSupport::Concern
7
-
8
- class_methods do
9
- def deliver_acidicly(recipients)
10
- new.deliver_acidicly(recipients)
11
- end
12
- end
13
-
14
- def deliver_acidicly(recipients)
15
- # THIS IS A HACK THAT COPIES AND PASTES KEY PARTS OF THE `Noticed::Base` CODE
16
- # IN ORDER TO ALLOW US TO TRANSACTIONALLY DELIVER NOTIFICATIONS
17
- # THIS IS THUS LIABLE TO BREAK WHENEVER THAT GEM IS UPDATED
18
- delivery_methods = self.class.delivery_methods.dup
19
-
20
- Array.wrap(recipients).uniq.each do |recipient|
21
- if (index = delivery_methods.find_index { |m| m[:name] == :database })
22
- database_delivery_method = delivery_methods.delete_at(index)
23
- self.record = run_delivery_method(database_delivery_method,
24
- recipient: recipient,
25
- enqueue: false,
26
- record: nil)
27
- end
28
-
29
- delivery_methods.map do |delivery_method|
30
- job_class = delivery_method_for(delivery_method[:name], delivery_method[:options])
31
- args = {
32
- notification_class: self.class.name,
33
- options: delivery_method[:options],
34
- params: params,
35
- recipient: recipient,
36
- record: record
37
- }
38
- serialized_job = job_class.send(:job_or_instantiate, args).serialize
39
- acidic_identifier = job_class.respond_to?(:acidic_identifier) ? job_class.acidic_identifier : :job_id
40
- key = IdempotencyKey.new(acidic_identifier).value_for(serialized_job)
41
-
42
- AcidicJob::Run.create!(
43
- staged: true,
44
- job_class: job_class.name,
45
- serialized_job: serialized_job,
46
- idempotency_key: key
47
- )
48
- end
49
- end
50
- end
51
- alias deliver_transactionally deliver_acidicly
52
- end
53
- end
54
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/concern"
4
- require "active_support/callbacks"
5
- require "active_support/core_ext/module/concerning"
6
-
7
- module AcidicJob
8
- module Extensions
9
- module Sidekiq
10
- extend ActiveSupport::Concern
11
-
12
- concerning :Serialization do
13
- class_methods do
14
- # called only from `AcidicJob::Run#enqueue_staged_job`
15
- def deserialize(serialized_job_hash)
16
- klass = if serialized_job_hash["class"].is_a?(Class)
17
- serialized_job_hash["class"]
18
- else
19
- serialized_job_hash["class"].constantize
20
- end
21
- worker = klass.new
22
- worker.jid = serialized_job_hash["jid"]
23
- worker.instance_variable_set(:@args, serialized_job_hash["args"])
24
-
25
- worker
26
- end
27
-
28
- # called only from `AcidicJob::PerformAcidicly#perform_acidicly`
29
- # and `AcidicJob::DeliverAcidicly#deliver_acidicly`
30
- def serialize_with_arguments(args = [], _kwargs = nil)
31
- # THIS IS A HACK THAT ESSENTIALLY COPIES THE CODE FROM THE SIDEKIQ CODEBASE TO MIMIC THE BEHAVIOR
32
- # updated to handle Sidekiq v6.4.2 at latest
33
- args = Array[args]
34
- normalized_args = ::Sidekiq.load_json(::Sidekiq.dump_json(args))
35
- item = { "class" => self, "args" => normalized_args }
36
- dummy_sidekiq_client = ::Sidekiq::Client.new
37
- normed = dummy_sidekiq_client.send :normalize_item, item
38
- redis_pool = dummy_sidekiq_client.instance_variable_get(:@redis_pool)
39
- dummy_sidekiq_client.middleware.invoke(normed["class"], normed, normed["queue"], redis_pool) do
40
- normed
41
- end
42
- end
43
- end
44
-
45
- def serialize_job(*args, **kwargs)
46
- # `@args` is only set via `deserialize`; it is not a standard Sidekiq thing
47
- arguments = args || @args
48
- arguments += [kwargs] unless kwargs.empty?
49
- normalized_args = ::Sidekiq.load_json(::Sidekiq.dump_json(arguments))
50
- item = { "class" => self.class.name, "args" => normalized_args, "jid" => jid }
51
- sidekiq_options = sidekiq_options_hash || {}
52
-
53
- sidekiq_options.merge(item)
54
- end
55
-
56
- # called only from `AcidicJob::Run#enqueue_staged_job`
57
- def enqueue
58
- ::Sidekiq::Client.push(
59
- "class" => self.class,
60
- "args" => @args,
61
- "jid" => @acidic_job_run&.staged_job_id || @jid
62
- )
63
- end
64
- end
65
-
66
- concerning :PerformAcidicly do
67
- class_methods do
68
- def perform_acidicly(*args, **kwargs)
69
- serialized_job = serialize_with_arguments(*args, **kwargs)
70
- key = IdempotencyKey.new(acidic_identifier).value_for(serialized_job)
71
-
72
- AcidicJob::Run.create!(
73
- staged: true,
74
- job_class: name,
75
- serialized_job: serialized_job,
76
- idempotency_key: key
77
- )
78
- end
79
- alias_method :perform_transactionally, :perform_acidicly
80
- end
81
- end
82
-
83
- # to balance `perform_async` class method
84
- concerning :PerformSync do
85
- class_methods do
86
- def perform_sync(*args, **kwargs)
87
- new.perform(*args, **kwargs)
88
- end
89
- end
90
- end
91
-
92
- # Following approach used by ActiveJob
93
- # https://github.com/rails/rails/blob/93c9534c9871d4adad4bc33b5edc355672b59c61/activejob/lib/active_job/callbacks.rb
94
- concerning :Callbacks do
95
- class_methods do
96
- def around_perform(*filters, &blk)
97
- set_callback(:perform, :around, *filters, &blk)
98
- end
99
-
100
- def before_perform(*filters, &blk)
101
- set_callback(:perform, :before, *filters, &blk)
102
- end
103
-
104
- def after_perform(*filters, &blk)
105
- set_callback(:perform, :after, *filters, &blk)
106
- end
107
- end
108
- end
109
- end
110
- end
111
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Represents an action to set a new API response (which will be stored onto an
4
- # idempotency key). One possible option for a return from an #atomic_phase
5
- # block.
6
- module AcidicJob
7
- class FinishedPoint
8
- def call(run:)
9
- # Skip AR callbacks as there are none on the model
10
- run.update_columns(
11
- locked_at: nil,
12
- recovery_point: Run::FINISHED_RECOVERY_POINT
13
- )
14
- end
15
- end
16
- end