acidic_job 0.9.0 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +4 -5
  3. data/.gitignore +1 -1
  4. data/.rubocop.yml +0 -10
  5. data/Gemfile.lock +117 -112
  6. data/README.md +123 -140
  7. data/acidic_job.gemspec +2 -0
  8. data/bin/sandbox +1958 -0
  9. data/gemfiles/{rails_6.1_sidekiq_6.4.gemfile → rails_6.1.gemfile} +0 -2
  10. data/gemfiles/{rails_7.0_sidekiq_6.4.gemfile → rails_7.0.gemfile} +0 -2
  11. data/lib/acidic_job/active_kiq.rb +15 -44
  12. data/lib/acidic_job/arguments.rb +0 -8
  13. data/lib/acidic_job/errors.rb +0 -1
  14. data/lib/acidic_job/mixin.rb +19 -30
  15. data/lib/acidic_job/perform_wrapper.rb +5 -5
  16. data/lib/acidic_job/processor.rb +9 -8
  17. data/lib/acidic_job/run.rb +6 -27
  18. data/lib/acidic_job/serializer.rb +2 -2
  19. data/lib/acidic_job/serializers/exception_serializer.rb +18 -23
  20. data/lib/acidic_job/serializers/job_serializer.rb +14 -6
  21. data/lib/acidic_job/serializers/worker_serializer.rb +6 -4
  22. data/lib/acidic_job/version.rb +1 -1
  23. data/lib/acidic_job/workflow.rb +8 -0
  24. data/lib/acidic_job.rb +10 -10
  25. metadata +35 -23
  26. data/.github/FUNDING.yml +0 -13
  27. data/gemfiles/rails_6.1_sidekiq_6.5.gemfile +0 -10
  28. data/gemfiles/rails_6.1_sidekiq_7.0.gemfile +0 -10
  29. data/gemfiles/rails_7.0_sidekiq_6.5.gemfile +0 -10
  30. data/gemfiles/rails_7.0_sidekiq_7.0.gemfile +0 -10
  31. data/gemfiles/rails_7.1_sidekiq_6.4.gemfile +0 -10
  32. data/gemfiles/rails_7.1_sidekiq_6.5.gemfile +0 -10
  33. data/gemfiles/rails_7.1_sidekiq_7.0.gemfile +0 -10
  34. data/lib/acidic_job/configured_job.rb +0 -11
  35. data/lib/acidic_job/extensions/action_mailer.rb +0 -19
  36. data/lib/acidic_job/extensions/noticed.rb +0 -46
  37. data/lib/acidic_job/perform_acidicly.rb +0 -23
  38. data/lib/acidic_job/railtie.rb +0 -44
  39. data/lib/acidic_job/serializers/active_kiq_serializer.rb +0 -25
  40. data/lib/acidic_job/serializers/new_record_serializer.rb +0 -25
  41. data/lib/acidic_job/test_case.rb +0 -9
  42. data/lib/acidic_job/testing.rb +0 -73
@@ -5,6 +5,4 @@ source "https://rubygems.org"
5
5
  gem "activemodel", "~> 6.1.0"
6
6
  gem "railties", "~> 6.1.0"
7
7
 
8
- gem "sidekiq", "~> 6.4.0"
9
-
10
8
  gemspec path: "../"
@@ -5,6 +5,4 @@ source "https://rubygems.org"
5
5
  gem "activemodel", "~> 7.0.0"
6
6
  gem "railties", "~> 7.0.0"
7
7
 
8
- gem "sidekiq", "~> 6.4.0"
9
-
10
8
  gemspec path: "../"
@@ -13,29 +13,11 @@ module AcidicJob
13
13
  define_callbacks :perform
14
14
  include Mixin
15
15
 
16
- concerning :Configuring do
17
- # Configures the job with the given options.
18
- def set(options = {}) # :nodoc:
19
- self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait]
20
- self.scheduled_at = options[:wait_until].to_f if options[:wait_until]
21
- self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue]
22
-
23
- self
24
- end
25
- end
26
-
27
16
  concerning :Initializing do
28
- class_methods do
29
- def job_or_instantiate(*args)
30
- args.first.is_a?(self) ? args.first : new(*args)
31
- end
32
- end
33
-
34
17
  included do
35
18
  attr_accessor :arguments
36
19
  attr_accessor :job_id
37
20
  attr_accessor :queue_name
38
- attr_accessor :scheduled_at
39
21
  attr_accessor :sidekiq_options
40
22
  end
41
23
  ##
@@ -43,9 +25,9 @@ module AcidicJob
43
25
  # +args+ are the arguments, if any, that will be passed to the perform method
44
26
  # +opts+ are any options to configure the job
45
27
  def initialize(*arguments)
46
- @arguments = arguments
47
- @job_id = ::SecureRandom.uuid
48
- @sidekiq_options = sidekiq_options_hash || ::Sidekiq.default_job_options
28
+ @arguments = arguments
29
+ @job_id = SecureRandom.uuid
30
+ @sidekiq_options = sidekiq_options_hash || Sidekiq.default_job_options
49
31
  @queue_name = @sidekiq_options["queue"]
50
32
  end
51
33
 
@@ -61,33 +43,22 @@ module AcidicJob
61
43
 
62
44
  concerning :Performing do
63
45
  class_methods do
64
- def perform_later(*args)
65
- perform_async(*args)
66
- end
67
-
68
- def perform_now(*args)
69
- perform_inline(*args)
46
+ def perform_now(*args, **kwargs)
47
+ new.perform(*args, **kwargs)
70
48
  end
71
49
  end
72
50
 
73
- def perform_later(*args)
74
- Setter.new(self.class, {}).perform_async(*args)
75
- end
76
-
77
- def perform_now(*args)
78
- Setter.new(self.class, {}).perform_inline(*args)
51
+ def perform_now(*args, **kwargs)
52
+ perform(*args, **kwargs)
79
53
  end
80
54
 
81
55
  def enqueue
82
- item = {
56
+ ::Sidekiq::Client.push(
83
57
  "class" => self.class,
84
58
  "args" => @arguments,
85
59
  "jid" => @job_id,
86
60
  "queue" => @queue_name
87
- }
88
- item["at"] = @scheduled_at if defined?(@scheduled_at) && @scheduled_at
89
-
90
- ::Sidekiq::Client.push(item)
61
+ )
91
62
  end
92
63
  end
93
64
 
@@ -126,16 +97,16 @@ module AcidicJob
126
97
  # https://github.com/rails/rails/blob/93c9534c9871d4adad4bc33b5edc355672b59c61/activejob/lib/active_job/callbacks.rb
127
98
  concerning :Callbacks do
128
99
  class_methods do
129
- def around_perform(...)
130
- set_callback(:perform, :around, ...)
100
+ def around_perform(*filters, &blk)
101
+ set_callback(:perform, :around, *filters, &blk)
131
102
  end
132
103
 
133
- def before_perform(...)
134
- set_callback(:perform, :before, ...)
104
+ def before_perform(*filters, &blk)
105
+ set_callback(:perform, :before, *filters, &blk)
135
106
  end
136
107
 
137
- def after_perform(...)
138
- set_callback(:perform, :after, ...)
108
+ def after_perform(*filters, &blk)
109
+ set_callback(:perform, :after, *filters, &blk)
139
110
  end
140
111
  end
141
112
  end
@@ -18,13 +18,5 @@ module AcidicJob
18
18
  rescue ActiveRecord::RecordNotFound
19
19
  nil
20
20
  end
21
-
22
- # In order to allow our `NewRecordSerializer` a chance to work, we need to ensure that
23
- # ActiveJob's first attempt to serialize an ActiveRecord model doesn't throw an exception.
24
- def convert_to_global_id_hash(argument)
25
- { GLOBALID_KEY => argument.to_global_id.to_s }
26
- rescue URI::GID::MissingModelIdError
27
- Serializers.serialize(argument)
28
- end
29
21
  end
30
22
  end
@@ -15,5 +15,4 @@ module AcidicJob
15
15
  class UnserializableValue < Error; end
16
16
  class LockedIdempotencyKey < Error; end
17
17
  class MismatchedIdempotencyKeyAndJobArguments < Error; end
18
- class MissingBlockArgument < Error; end
19
18
  end
@@ -7,11 +7,12 @@ module AcidicJob
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  def self.wire_up(other)
10
+ raise UnknownJobAdapter unless (defined?(::ActiveJob::Base) && other < ::ActiveJob::Base) ||
11
+ (defined?(::Sidekiq::Worker) && other.include?(::Sidekiq::Worker))
12
+
10
13
  # Ensure our `perform` method always runs first to gather parameters
11
14
  # and run perform callbacks for Sidekiq workers
12
15
  other.prepend PerformWrapper
13
- # Ensure both configured and base jobs can be performed acidicly
14
- other.include PerformAcidicly
15
16
 
16
17
  # By default, we unique job runs by the `job_id`
17
18
  other.instance_variable_set(:@acidic_identifier, :job_id)
@@ -20,7 +21,7 @@ module AcidicJob
20
21
  # You could unique job runs by the arguments passed to the job (e.g. memoization)
21
22
  other.define_singleton_method(:acidic_by_job_arguments) { @acidic_identifier = :job_arguments }
22
23
  # Or, you could unique jobs run by any logic you'd like using a block
23
- other.define_singleton_method(:acidic_by) { |proc = nil, &block| @acidic_identifier = proc || block }
24
+ other.define_singleton_method(:acidic_by) { |&block| @acidic_identifier = block }
24
25
 
25
26
  # We add a callback to ensure that staged, non-workflow jobs are "finished" after they are "performed".
26
27
  # This allows us to ensure that we can always inspect whether a run is finished and get correct data
@@ -42,6 +43,15 @@ module AcidicJob
42
43
  super
43
44
  end
44
45
 
46
+ # `perform_now` runs a job synchronously and immediately
47
+ # `perform_later` runs a job asynchronously and queues it immediately
48
+ # `perform_acidicly` run a job asynchronously and queues it after a successful database commit
49
+ def perform_acidicly(*args)
50
+ job = new(*args)
51
+
52
+ Run.stage!(job)
53
+ end
54
+
45
55
  # Instantiate an instance of a job ready for serialization
46
56
  def with(...)
47
57
  # New delegation syntax (...) was introduced in Ruby 2.7.
@@ -51,26 +61,12 @@ module AcidicJob
51
61
  job.queue_name
52
62
  job
53
63
  end
54
-
55
- def set(options = {})
56
- ::AcidicJob::ConfiguredJob.new(self, options)
57
- end
58
64
  end
59
65
 
60
66
  def idempotency_key
61
67
  IdempotencyKey.new(self).value(acidic_by: acidic_identifier)
62
68
  end
63
69
 
64
- # Configures the job with the given options.
65
- def set(options = {}) # :nodoc:
66
- self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait]
67
- self.scheduled_at = options[:wait_until].to_f if options[:wait_until]
68
- self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue]
69
- self.priority = options[:priority].to_i if options[:priority]
70
-
71
- self
72
- end
73
-
74
70
  protected
75
71
 
76
72
  # Short circuits execution by sending execution right to 'finished'.
@@ -80,16 +76,17 @@ module AcidicJob
80
76
  end
81
77
 
82
78
  def with_acidic_workflow(persisting: {}, &block)
83
- raise UnknownJobAdapter unless known_job_adapter?
84
-
85
79
  raise RedefiningWorkflow if defined? @workflow_builder
86
80
 
87
81
  @workflow_builder = WorkflowBuilder.new
88
82
 
89
83
  raise MissingWorkflowBlock, "A block must be passed to `with_acidic_workflow`" unless block_given?
90
- raise MissingBlockArgument, "An argument must be passed to the `with_acidic_workflow` block" if block.arity.zero?
91
84
 
92
- block.call @workflow_builder
85
+ if block.arity.zero?
86
+ @workflow_builder.instance_exec(&block)
87
+ else
88
+ yield @workflow_builder
89
+ end
93
90
 
94
91
  raise NoDefinedSteps if @workflow_builder.steps.empty?
95
92
 
@@ -233,7 +230,7 @@ module AcidicJob
233
230
 
234
231
  # "STG__#{idempotency_key}__#{encoded_global_id}"
235
232
  _prefix, _idempotency_key, encoded_global_id = job_id.split("__")
236
- staged_job_gid = "gid://#{::Base64.urlsafe_decode64(encoded_global_id)}"
233
+ staged_job_gid = "gid://#{::Base64.decode64(encoded_global_id)}"
237
234
 
238
235
  @staged_job_run = ::GlobalID::Locator.locate(staged_job_gid)
239
236
  end
@@ -252,13 +249,5 @@ module AcidicJob
252
249
  :serializable
253
250
  end
254
251
  end
255
-
256
- def known_job_adapter?
257
- return true if defined?(::AcidicJob::Base) && self.class < ::AcidicJob::Base
258
- return true if defined?(::AcidicJob::ActiveKiq) && self.class < ::AcidicJob::ActiveKiq
259
- return true if defined?(::ActiveJob) && self.class < ::ActiveJob::Base
260
-
261
- false
262
- end
263
252
  end
264
253
  end
@@ -4,15 +4,15 @@ module AcidicJob
4
4
  # NOTE: it is essential that this be a bare module and not an ActiveSupport::Concern
5
5
  # WHY?
6
6
  module PerformWrapper
7
- ruby2_keywords def perform(*args)
7
+ def perform(*args, **kwargs)
8
8
  @arguments = args
9
9
 
10
10
  # we don't want to run the `perform` callbacks twice, since ActiveJob already handles that for us
11
- if defined?(::ActiveJob) && self.class < ::ActiveJob::Base
12
- super(*args)
13
- elsif defined?(::Sidekiq) && self.class.include?(::Sidekiq::Worker)
11
+ if defined?(ActiveJob) && self.class < ActiveJob::Base
12
+ super(*args, **kwargs)
13
+ elsif defined?(Sidekiq) && self.class.include?(Sidekiq::Worker)
14
14
  run_callbacks :perform do
15
- super(*args)
15
+ super(*args, **kwargs)
16
16
  end
17
17
  else
18
18
  raise UnknownJobAdapter
@@ -19,7 +19,7 @@ module AcidicJob
19
19
  if !@run.known_recovery_point?
20
20
  raise UnknownRecoveryPoint,
21
21
  "Defined workflow does not reference this step: #{@run.current_step_name.inspect}"
22
- elsif (awaited_jobs = jobs_from(@run.current_step_awaits)).any?
22
+ elsif !Array(awaited_jobs = @run.current_step_hash.fetch("awaits", [])).compact.empty?
23
23
  # We only execute the current step, without progressing to the next step.
24
24
  # This ensures that any failures in parallel jobs will have this step retried in the main workflow
25
25
  step_result = @workflow.execute_current_step
@@ -47,12 +47,14 @@ module AcidicJob
47
47
 
48
48
  private
49
49
 
50
- def enqueue_awaited_jobs(awaited_jobs, step_result)
50
+ def enqueue_awaited_jobs(jobs_or_jobs_getter, step_result)
51
+ awaited_jobs = jobs_from(jobs_or_jobs_getter)
52
+
51
53
  AcidicJob.logger.log_run_event("Enqueuing #{awaited_jobs.count} awaited jobs...", @job, @run)
52
54
  # All jobs created in the block are pushed atomically at the end of the block.
53
55
  AcidicJob::Run.transaction do
54
56
  awaited_jobs.each do |awaited_job|
55
- worker_class, args = job_and_args(awaited_job)
57
+ worker_class, args = job_args_and_kwargs(awaited_job)
56
58
 
57
59
  job = worker_class.new(*args)
58
60
 
@@ -65,11 +67,10 @@ module AcidicJob
65
67
  def jobs_from(jobs_or_jobs_getter)
66
68
  case jobs_or_jobs_getter
67
69
  when Array
68
- jobs_or_jobs_getter.compact
70
+ jobs_or_jobs_getter
69
71
  when Symbol, String
70
- if @job.respond_to?(jobs_or_jobs_getter, _include_private = true)
71
- jobs = @job.method(jobs_or_jobs_getter).call
72
- Array(jobs).compact
72
+ if @job.respond_to?(jobs_or_jobs_getter)
73
+ @job.method(jobs_or_jobs_getter).call
73
74
  else
74
75
  raise UnknownAwaitedJob,
75
76
  "Invalid `awaits`; unknown method `#{jobs_or_jobs_getter}` for this job"
@@ -80,7 +81,7 @@ module AcidicJob
80
81
  end
81
82
  end
82
83
 
83
- def job_and_args(job)
84
+ def job_args_and_kwargs(job)
84
85
  case job
85
86
  when Class
86
87
  [job, []]
@@ -15,10 +15,6 @@ module AcidicJob
15
15
  STAGED_JOB_ID_PREFIX = "STG"
16
16
  STAGED_JOB_ID_DELIMITER = "__"
17
17
  IDEMPOTENCY_KEY_LOCK_TIMEOUT_SECONDS = 2
18
- RAILS_VERSION = Gem::Version.new(ActiveRecord.version)
19
- TARGET_VERSION = Gem::Version.new("7.1")
20
- REQUIRES_CODER_FOR_SERIALIZE = RAILS_VERSION >= TARGET_VERSION ||
21
- RAILS_VERSION.segments[..1] == TARGET_VERSION.segments
22
18
 
23
19
  self.table_name = "acidic_job_runs"
24
20
 
@@ -51,11 +47,7 @@ module AcidicJob
51
47
 
52
48
  after_update_commit :proceed_with_parent, if: :finished?
53
49
 
54
- if REQUIRES_CODER_FOR_SERIALIZE
55
- serialize :returning_to, coder: AcidicJob::Serializer
56
- else
57
- serialize :returning_to, AcidicJob::Serializer
58
- end
50
+ serialize :returning_to, AcidicJob::Serializer
59
51
  end
60
52
 
61
53
  class_methods do
@@ -125,7 +117,7 @@ module AcidicJob
125
117
  staged: true,
126
118
  job_class: job.class.name,
127
119
  serialized_job: job.serialize,
128
- idempotency_key: job.try(:idempotency_key) || job.job_id
120
+ idempotency_key: job.idempotency_key
129
121
  )
130
122
  end
131
123
  end
@@ -138,7 +130,7 @@ module AcidicJob
138
130
  # encode the identifier for this record in the job ID
139
131
  global_id = to_global_id.to_s.remove("gid://")
140
132
  # base64 encoding for minimal security
141
- encoded_global_id = Base64.urlsafe_encode64(global_id, padding: false)
133
+ encoded_global_id = Base64.encode64(global_id).strip
142
134
 
143
135
  [
144
136
  STAGED_JOB_ID_PREFIX,
@@ -150,13 +142,8 @@ module AcidicJob
150
142
 
151
143
  concerning :Workflowable do
152
144
  included do
153
- if REQUIRES_CODER_FOR_SERIALIZE
154
- serialize :workflow, coder: AcidicJob::Serializer
155
- serialize :error_object, coder: AcidicJob::Serializer
156
- else
157
- serialize :workflow, AcidicJob::Serializer
158
- serialize :error_object, AcidicJob::Serializer
159
- end
145
+ serialize :workflow, AcidicJob::Serializer
146
+ serialize :error_object, AcidicJob::Serializer
160
147
  store :attr_accessors, coder: AcidicJob::Serializer
161
148
 
162
149
  with_options unless: :staged? do
@@ -186,10 +173,6 @@ module AcidicJob
186
173
  current_step_hash.fetch("then")
187
174
  end
188
175
 
189
- def current_step_awaits
190
- current_step_hash["awaits"]
191
- end
192
-
193
176
  def next_step_finishes?
194
177
  next_step_name.to_s == FINISHED_RECOVERY_POINT
195
178
  end
@@ -201,11 +184,7 @@ module AcidicJob
201
184
 
202
185
  concerning :Jobbable do
203
186
  included do
204
- if REQUIRES_CODER_FOR_SERIALIZE
205
- serialize :serialized_job, coder: JSON
206
- else
207
- serialize :serialized_job, JSON
208
- end
187
+ serialize :serialized_job, JSON
209
188
 
210
189
  validates :serialized_job, presence: true
211
190
  validates :job_class, presence: true
@@ -10,11 +10,11 @@ module AcidicJob
10
10
  return if json.nil? || json.empty?
11
11
 
12
12
  data = JSON.parse(json)
13
- Arguments.send :deserialize_argument, data
13
+ Arguments.deserialize(data).first
14
14
  end
15
15
 
16
16
  def dump(obj)
17
- data = Arguments.send :serialize_argument, obj
17
+ data = Arguments.serialize [obj]
18
18
  data.to_json
19
19
  rescue ActiveJob::SerializationError
20
20
  raise UnserializableValue
@@ -6,36 +6,31 @@ module AcidicJob
6
6
  module Serializers
7
7
  class ExceptionSerializer < ::ActiveJob::Serializers::ObjectSerializer
8
8
  def serialize(exception)
9
- compressed_backtrace = {}
10
- exception.backtrace&.map do |trace|
9
+ hash = {
10
+ "class" => exception.class.name,
11
+ "message" => exception.message,
12
+ "cause" => exception.cause,
13
+ "backtrace" => {}
14
+ }
15
+
16
+ exception.backtrace.map do |trace|
11
17
  path, _, location = trace.rpartition("/")
12
- next if compressed_backtrace.key?(path)
13
18
 
14
- compressed_backtrace[path] = location
19
+ next if hash["backtrace"].key?(path)
20
+
21
+ hash["backtrace"][path] = location
15
22
  end
16
- exception.set_backtrace(compressed_backtrace.map do |path, location|
17
- [path, location].join("/")
18
- end)
19
- exception.cause&.set_backtrace([])
20
23
 
21
- super({ "yaml" => exception.to_yaml })
24
+ super(hash)
22
25
  end
23
26
 
24
27
  def deserialize(hash)
25
- if hash.key?("class")
26
- exception_class = hash["class"].constantize
27
- exception = exception_class.new(hash["message"])
28
- exception.set_backtrace(hash["backtrace"].map do |path, location|
29
- [path, location].join("/")
30
- end)
31
- exception
32
- elsif hash.key?("yaml")
33
- if YAML.respond_to?(:unsafe_load)
34
- YAML.unsafe_load(hash["yaml"])
35
- else
36
- YAML.load(hash["yaml"]) # rubocop:disable Security/YAMLLoad
37
- end
38
- end
28
+ exception_class = hash["class"].constantize
29
+ exception = exception_class.new(hash["message"])
30
+ exception.set_backtrace(hash["backtrace"].map do |path, location|
31
+ [path, location].join("/")
32
+ end)
33
+ exception
39
34
  end
40
35
 
41
36
  def serialize?(argument)
@@ -6,16 +6,24 @@ module AcidicJob
6
6
  module Serializers
7
7
  class JobSerializer < ::ActiveJob::Serializers::ObjectSerializer
8
8
  def serialize(job)
9
- # don't serialize the `enqueued_at` value, as ActiveRecord will check if the Run record has changed
10
- # by comparing the deserialized database value with a temporary in-memory generated value.
11
- # That temporary in-memory generated value can sometimes have an `enqueued_at` value that is 1 second off
12
- # from the original. In this case, ActiveRecord will think the record has unsaved changes and block the lock.
13
- super(job.serialize.except("enqueued_at"))
9
+ super(job.serialize)
14
10
  end
15
11
 
16
12
  def deserialize(hash)
17
- job = ::ActiveJob::Base.deserialize(hash)
13
+ job = ActiveJob::Base.deserialize(hash)
18
14
  job.send(:deserialize_arguments_if_needed)
15
+ # this is a shim to ensure we can work with Ruby 2.7 as well as 3.0+
16
+ # :nocov:
17
+ if job.arguments.last.is_a?(Hash)
18
+ *args, kwargs = job.arguments
19
+ else
20
+ args = job.arguments
21
+ kwargs = {}
22
+ end
23
+ # :nocov:
24
+ job.instance_variable_set(:@__acidic_job_args, args)
25
+ job.instance_variable_set(:@__acidic_job_kwargs, kwargs)
26
+
19
27
  job
20
28
  end
21
29
 
@@ -2,24 +2,26 @@
2
2
 
3
3
  require "active_job/serializers/object_serializer"
4
4
 
5
+ # :nocov:
5
6
  module AcidicJob
6
7
  module Serializers
7
8
  class WorkerSerializer < ::ActiveJob::Serializers::ObjectSerializer
8
9
  def serialize(worker)
9
10
  super(
10
- "job_class" => worker.class.name
11
+ "job_class" => worker.class.name,
12
+ "arguments" => worker.arguments,
11
13
  )
12
14
  end
13
15
 
14
16
  def deserialize(hash)
15
17
  worker_class = hash["job_class"].constantize
16
- worker_class.new
18
+ worker_class.new(*hash["arguments"])
17
19
  end
18
20
 
19
21
  def serialize?(argument)
20
- defined?(::Sidekiq) && argument.class.include?(::Sidekiq::Worker) &&
21
- !(defined?(::AcidicJob::ActiveKiq) && argument.class < ::AcidicJob::ActiveKiq)
22
+ defined?(::Sidekiq) && argument.class.include?(::Sidekiq::Worker)
22
23
  end
23
24
  end
24
25
  end
25
26
  end
27
+ # :nocov:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcidicJob
4
- VERSION = "0.9.0"
4
+ VERSION = "1.0.0.beta.1"
5
5
  end
@@ -50,6 +50,10 @@ module AcidicJob
50
50
  wrapped_method = WorkflowStep.new(run: @run, job: @job).wrapped
51
51
  current_step = @run.current_step_name
52
52
 
53
+ # can't reproduce yet, but saw a bug in production where
54
+ # nested awaits workflows had an unsaved `workflow` attribute
55
+ @run.save! if @run.has_changes_to_save?
56
+
53
57
  AcidicJob.logger.log_run_event("Executing #{current_step}...", @job, @run)
54
58
  @run.with_lock do
55
59
  @step_result = wrapped_method.call(@run)
@@ -60,6 +64,10 @@ module AcidicJob
60
64
  def run_step_result
61
65
  next_step = @run.next_step_name
62
66
 
67
+ # can't reproduce yet, but saw a bug in production where
68
+ # nested awaits workflows had an unsaved `workflow` attribute
69
+ @run.save! if @run.has_changes_to_save?
70
+
63
71
  AcidicJob.logger.log_run_event("Progressing to #{next_step}...", @job, @run)
64
72
  @run.with_lock do
65
73
  @step_result.call(run: @run)
data/lib/acidic_job.rb CHANGED
@@ -5,7 +5,6 @@ require_relative "acidic_job/errors"
5
5
  require_relative "acidic_job/logger"
6
6
  require_relative "acidic_job/arguments"
7
7
  require_relative "acidic_job/serializer"
8
- require_relative "acidic_job/configured_job"
9
8
  require_relative "acidic_job/workflow_builder"
10
9
  require_relative "acidic_job/idempotency_key"
11
10
  require_relative "acidic_job/recovery_point"
@@ -15,24 +14,25 @@ require_relative "acidic_job/workflow_step"
15
14
  require_relative "acidic_job/workflow"
16
15
  require_relative "acidic_job/processor"
17
16
  require_relative "acidic_job/perform_wrapper"
18
- require_relative "acidic_job/perform_acidicly"
19
- require_relative "acidic_job/extensions/action_mailer"
20
- require_relative "acidic_job/extensions/noticed"
21
17
  require_relative "acidic_job/mixin"
22
18
  require_relative "acidic_job/base"
23
- # require_relative "acidic_job/active_kiq"
19
+ require_relative "acidic_job/active_kiq"
24
20
 
25
- require "active_job/serializers"
26
21
  require_relative "acidic_job/serializers/exception_serializer"
27
22
  require_relative "acidic_job/serializers/finished_point_serializer"
28
23
  require_relative "acidic_job/serializers/job_serializer"
29
24
  require_relative "acidic_job/serializers/range_serializer"
30
25
  require_relative "acidic_job/serializers/recovery_point_serializer"
31
26
  require_relative "acidic_job/serializers/worker_serializer"
32
- require_relative "acidic_job/serializers/active_kiq_serializer"
33
- require_relative "acidic_job/serializers/new_record_serializer"
34
-
35
- require_relative "acidic_job/railtie"
27
+ require "active_job/serializers"
36
28
 
37
29
  module AcidicJob
30
+ ::ActiveJob::Serializers.add_serializers(
31
+ Serializers::ExceptionSerializer,
32
+ Serializers::FinishedPointSerializer,
33
+ Serializers::JobSerializer,
34
+ Serializers::RangeSerializer,
35
+ Serializers::RecoveryPointSerializer,
36
+ Serializers::WorkerSerializer
37
+ )
38
38
  end