acidic_job 1.0.0.pre28 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +13 -0
  3. data/.github/workflows/main.yml +12 -15
  4. data/.gitignore +3 -1
  5. data/.rubocop.yml +50 -5
  6. data/.ruby-version +1 -0
  7. data/Gemfile.lock +114 -198
  8. data/README.md +163 -246
  9. data/TODO +77 -0
  10. data/acidic_job.gemspec +8 -10
  11. data/app/models/acidic_job/entry.rb +19 -0
  12. data/app/models/acidic_job/execution.rb +50 -0
  13. data/app/models/acidic_job/record.rb +11 -0
  14. data/app/models/acidic_job/value.rb +7 -0
  15. data/bin/console +5 -2
  16. data/bin/test_all +26 -0
  17. data/gemfiles/rails_7.0.gemfile +4 -1
  18. data/gemfiles/rails_7.1.gemfile +11 -0
  19. data/gemfiles/rails_7.2.gemfile +11 -0
  20. data/gemfiles/rails_8.0.gemfile +11 -0
  21. data/lib/acidic_job/arguments.rb +31 -0
  22. data/lib/acidic_job/builder.rb +29 -0
  23. data/lib/acidic_job/context.rb +26 -0
  24. data/lib/acidic_job/engine.rb +46 -0
  25. data/lib/acidic_job/errors.rb +91 -12
  26. data/lib/acidic_job/log_subscriber.rb +50 -0
  27. data/lib/acidic_job/serializers/exception_serializer.rb +31 -0
  28. data/lib/acidic_job/serializers/job_serializer.rb +27 -0
  29. data/lib/acidic_job/serializers/new_record_serializer.rb +25 -0
  30. data/lib/acidic_job/serializers/range_serializer.rb +28 -0
  31. data/lib/acidic_job/testing.rb +8 -12
  32. data/lib/acidic_job/version.rb +1 -1
  33. data/lib/acidic_job/workflow.rb +185 -0
  34. data/lib/acidic_job.rb +15 -284
  35. data/lib/generators/acidic_job/install_generator.rb +3 -3
  36. data/lib/generators/acidic_job/templates/create_acidic_job_tables_migration.rb.erb +33 -0
  37. metadata +45 -115
  38. data/.ruby_version +0 -1
  39. data/.tool-versions +0 -1
  40. data/gemfiles/rails_6.1.gemfile +0 -8
  41. data/lib/acidic_job/awaiting.rb +0 -98
  42. data/lib/acidic_job/extensions/action_mailer.rb +0 -29
  43. data/lib/acidic_job/extensions/active_job.rb +0 -40
  44. data/lib/acidic_job/extensions/noticed.rb +0 -54
  45. data/lib/acidic_job/extensions/sidekiq.rb +0 -111
  46. data/lib/acidic_job/finished_point.rb +0 -16
  47. data/lib/acidic_job/idempotency_key.rb +0 -82
  48. data/lib/acidic_job/perform_wrapper.rb +0 -22
  49. data/lib/acidic_job/recovery_point.rb +0 -18
  50. data/lib/acidic_job/rspec_configuration.rb +0 -31
  51. data/lib/acidic_job/run.rb +0 -100
  52. data/lib/acidic_job/serializer.rb +0 -163
  53. data/lib/acidic_job/staging.rb +0 -38
  54. data/lib/acidic_job/step.rb +0 -104
  55. data/lib/acidic_job/test_case.rb +0 -9
  56. data/lib/acidic_job/upgrade_service.rb +0 -118
  57. data/lib/generators/acidic_job/drop_tables_generator.rb +0 -26
  58. data/lib/generators/acidic_job/templates/create_acidic_job_runs_migration.rb.erb +0 -19
  59. data/lib/generators/acidic_job/templates/drop_acidic_job_keys_migration.rb.erb +0 -27
metadata CHANGED
@@ -1,115 +1,87 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acidic_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre28
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - fractaledmind
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-03 00:00:00.000000000 Z
11
+ date: 2024-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activerecord
14
+ name: activejob
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '7.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '7.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activesupport
28
+ name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '7.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '7.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: database_cleaner
42
+ name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '7.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '7.1'
55
55
  - !ruby/object:Gem::Dependency
56
- name: activejob
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: combustion
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: minitest
56
+ name: railties
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
59
  - - ">="
88
60
  - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
61
+ version: '7.1'
62
+ type: :runtime
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - ">="
95
67
  - !ruby/object:Gem::Version
96
- version: '0'
68
+ version: '7.1'
97
69
  - !ruby/object:Gem::Dependency
98
- name: net-smtp
70
+ name: chaotic_job
99
71
  requirement: !ruby/object:Gem::Requirement
100
72
  requirements:
101
73
  - - ">="
102
74
  - !ruby/object:Gem::Version
103
- version: '0'
75
+ version: 0.2.0
104
76
  type: :development
105
77
  prerelease: false
106
78
  version_requirements: !ruby/object:Gem::Requirement
107
79
  requirements:
108
80
  - - ">="
109
81
  - !ruby/object:Gem::Version
110
- version: '0'
82
+ version: 0.2.0
111
83
  - !ruby/object:Gem::Dependency
112
- name: noticed
84
+ name: combustion
113
85
  requirement: !ruby/object:Gem::Requirement
114
86
  requirements:
115
87
  - - ">="
@@ -123,21 +95,7 @@ dependencies:
123
95
  - !ruby/object:Gem::Version
124
96
  version: '0'
125
97
  - !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
98
+ name: minitest
141
99
  requirement: !ruby/object:Gem::Requirement
142
100
  requirements:
143
101
  - - ">="
@@ -206,20 +164,6 @@ dependencies:
206
164
  - - ">="
207
165
  - !ruby/object:Gem::Version
208
166
  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
167
  - !ruby/object:Gem::Dependency
224
168
  name: simplecov
225
169
  requirement: !ruby/object:Gem::Requirement
@@ -248,20 +192,6 @@ dependencies:
248
192
  - - ">="
249
193
  - !ruby/object:Gem::Version
250
194
  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
195
  description: Idempotent operations for Rails apps, built on top of ActiveJob.
266
196
  email:
267
197
  - stephen.margheim@gmail.com
@@ -269,48 +199,48 @@ executables: []
269
199
  extensions: []
270
200
  extra_rdoc_files: []
271
201
  files:
202
+ - ".github/FUNDING.yml"
272
203
  - ".github/workflows/main.yml"
273
204
  - ".gitignore"
274
205
  - ".rubocop.yml"
275
- - ".ruby_version"
276
- - ".tool-versions"
206
+ - ".ruby-version"
277
207
  - Gemfile
278
208
  - Gemfile.lock
279
209
  - LICENSE
280
210
  - README.md
281
211
  - Rakefile
212
+ - TODO
282
213
  - UPGRADE_GUIDE.md
283
214
  - acidic_job.gemspec
215
+ - app/models/acidic_job/entry.rb
216
+ - app/models/acidic_job/execution.rb
217
+ - app/models/acidic_job/record.rb
218
+ - app/models/acidic_job/value.rb
284
219
  - bin/console
285
220
  - bin/setup
221
+ - bin/test_all
286
222
  - blog_post.md
287
223
  - combustion/log/test.log
288
- - gemfiles/rails_6.1.gemfile
289
224
  - gemfiles/rails_7.0.gemfile
225
+ - gemfiles/rails_7.1.gemfile
226
+ - gemfiles/rails_7.2.gemfile
227
+ - gemfiles/rails_8.0.gemfile
290
228
  - lib/acidic_job.rb
291
- - lib/acidic_job/awaiting.rb
229
+ - lib/acidic_job/arguments.rb
230
+ - lib/acidic_job/builder.rb
231
+ - lib/acidic_job/context.rb
232
+ - lib/acidic_job/engine.rb
292
233
  - 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
234
+ - lib/acidic_job/log_subscriber.rb
235
+ - lib/acidic_job/serializers/exception_serializer.rb
236
+ - lib/acidic_job/serializers/job_serializer.rb
237
+ - lib/acidic_job/serializers/new_record_serializer.rb
238
+ - lib/acidic_job/serializers/range_serializer.rb
307
239
  - lib/acidic_job/testing.rb
308
- - lib/acidic_job/upgrade_service.rb
309
240
  - lib/acidic_job/version.rb
310
- - lib/generators/acidic_job/drop_tables_generator.rb
241
+ - lib/acidic_job/workflow.rb
311
242
  - 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
243
+ - lib/generators/acidic_job/templates/create_acidic_job_tables_migration.rb.erb
314
244
  homepage: https://github.com/fractaledmind/acidic_job
315
245
  licenses:
316
246
  - MIT
@@ -330,11 +260,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
330
260
  version: 2.7.0
331
261
  required_rubygems_version: !ruby/object:Gem::Requirement
332
262
  requirements:
333
- - - ">"
263
+ - - ">="
334
264
  - !ruby/object:Gem::Version
335
- version: 1.3.1
265
+ version: '0'
336
266
  requirements: []
337
- rubygems_version: 3.3.7
267
+ rubygems_version: 3.5.21
338
268
  signing_key:
339
269
  specification_version: 4
340
270
  summary: Idempotent operations for Rails apps, built on top of ActiveJob.
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,98 +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
- step = Step.new(current_step, run, job, step_result)
31
- # TODO: WRITE REGRESSION TESTS FOR PARALLEL JOB FAILING AND RETRYING THE ORIGINAL STEP
32
- step.progress
33
-
34
- return if run.finished?
35
-
36
- # when a batch of jobs for a step succeeds, we begin processing the `AcidicJob::Run` record again
37
- # process_run(run)
38
- run.update_column(:locked_at, nil)
39
- job.enqueue
40
- end
41
-
42
- def enqueue_step_parallel_jobs(jobs_or_jobs_getter, run, step_result)
43
- awaited_jobs = case jobs_or_jobs_getter
44
- when Array
45
- jobs_or_jobs_getter
46
- when Symbol, String
47
- method(jobs_or_jobs_getter).call
48
- end
49
-
50
- AcidicJob::Run.transaction do
51
- awaited_jobs.compact.each do |awaited_job|
52
- worker_class, args, kwargs = job_args_and_kwargs(awaited_job)
53
-
54
- job = worker_class.new(*args, **kwargs)
55
-
56
- AcidicJob::Run.create!(
57
- staged: true,
58
- awaited_by: run,
59
- job_class: worker_class,
60
- serialized_job: job.serialize_job(*args, **kwargs),
61
- idempotency_key: job.idempotency_key
62
- )
63
- run.update(returning_to: step_result)
64
- end
65
- end
66
- end
67
-
68
- def step_done(_status, options)
69
- run = Run.find(options["run_id"])
70
- current_step = run.workflow[run.recovery_point.to_s]
71
- # re-hydrate the `step_result` object
72
- step_result = YAML.safe_load(options["step_result_yaml"], permitted_classes: [RecoveryPoint, FinishedPoint])
73
- step = Step.new(current_step, run, self, step_result)
74
-
75
- # TODO: WRITE REGRESSION TESTS FOR PARALLEL JOB FAILING AND RETRYING THE ORIGINAL STEP
76
- step.progress
77
- # when a batch of jobs for a step succeeds, we begin processing the `AcidicJob::Run` record again
78
- process_run(run)
79
- end
80
-
81
- def job_args_and_kwargs(job)
82
- case job
83
- when Class
84
- [job, [], {}]
85
- when String
86
- [job.constantize, [], {}]
87
- when Symbol
88
- [job.to_s.constantize, [], {}]
89
- else
90
- [
91
- job.class,
92
- job.instance_variable_get(:@__acidic_job_args),
93
- job.instance_variable_get(:@__acidic_job_kwargs)
94
- ]
95
- end
96
- end
97
- end
98
- 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