rocketjob 5.1.1 → 5.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rocketjob +2 -2
  3. data/bin/rocketjob_batch_perf +1 -1
  4. data/bin/rocketjob_perf +1 -1
  5. data/lib/rocket_job/active_worker.rb +1 -0
  6. data/lib/rocket_job/batch.rb +16 -17
  7. data/lib/rocket_job/batch/callbacks.rb +1 -2
  8. data/lib/rocket_job/batch/io.rb +10 -6
  9. data/lib/rocket_job/batch/logger.rb +2 -2
  10. data/lib/rocket_job/batch/lower_priority.rb +2 -2
  11. data/lib/rocket_job/batch/model.rb +23 -23
  12. data/lib/rocket_job/batch/performance.rb +19 -21
  13. data/lib/rocket_job/batch/result.rb +1 -1
  14. data/lib/rocket_job/batch/results.rb +1 -1
  15. data/lib/rocket_job/batch/state_machine.rb +5 -6
  16. data/lib/rocket_job/batch/statistics.rb +10 -8
  17. data/lib/rocket_job/batch/tabular.rb +2 -2
  18. data/lib/rocket_job/batch/tabular/input.rb +11 -7
  19. data/lib/rocket_job/batch/tabular/output.rb +1 -1
  20. data/lib/rocket_job/batch/throttle.rb +11 -30
  21. data/lib/rocket_job/batch/{throttle_running_slices.rb → throttle_running_workers.rb} +13 -10
  22. data/lib/rocket_job/batch/worker.rb +102 -85
  23. data/lib/rocket_job/cli.rb +57 -54
  24. data/lib/rocket_job/config.rb +8 -10
  25. data/lib/rocket_job/dirmon_entry.rb +13 -10
  26. data/lib/rocket_job/event.rb +16 -16
  27. data/lib/rocket_job/extensions/mongo/logging.rb +2 -2
  28. data/lib/rocket_job/extensions/mongoid/clients/options.rb +2 -2
  29. data/lib/rocket_job/extensions/mongoid/contextual/mongo.rb +4 -2
  30. data/lib/rocket_job/extensions/mongoid/factory.rb +13 -5
  31. data/lib/rocket_job/extensions/rocket_job_adapter.rb +2 -1
  32. data/lib/rocket_job/job_exception.rb +0 -3
  33. data/lib/rocket_job/jobs/dirmon_job.rb +4 -4
  34. data/lib/rocket_job/jobs/housekeeping_job.rb +7 -7
  35. data/lib/rocket_job/jobs/on_demand_batch_job.rb +14 -4
  36. data/lib/rocket_job/jobs/on_demand_job.rb +3 -3
  37. data/lib/rocket_job/jobs/performance_job.rb +1 -1
  38. data/lib/rocket_job/jobs/re_encrypt/relational_job.rb +11 -10
  39. data/lib/rocket_job/jobs/upload_file_job.rb +9 -5
  40. data/lib/rocket_job/performance.rb +24 -22
  41. data/lib/rocket_job/plugins/cron.rb +7 -3
  42. data/lib/rocket_job/plugins/document.rb +7 -5
  43. data/lib/rocket_job/plugins/job/callbacks.rb +1 -1
  44. data/lib/rocket_job/plugins/job/logger.rb +3 -3
  45. data/lib/rocket_job/plugins/job/model.rb +34 -27
  46. data/lib/rocket_job/plugins/job/persistence.rb +7 -34
  47. data/lib/rocket_job/plugins/job/state_machine.rb +5 -4
  48. data/lib/rocket_job/plugins/job/throttle.rb +12 -28
  49. data/lib/rocket_job/plugins/job/throttle_running_jobs.rb +2 -2
  50. data/lib/rocket_job/plugins/job/worker.rb +22 -70
  51. data/lib/rocket_job/plugins/processing_window.rb +5 -4
  52. data/lib/rocket_job/plugins/restart.rb +3 -3
  53. data/lib/rocket_job/plugins/retry.rb +2 -2
  54. data/lib/rocket_job/plugins/singleton.rb +1 -2
  55. data/lib/rocket_job/plugins/state_machine.rb +4 -4
  56. data/lib/rocket_job/plugins/transaction.rb +1 -1
  57. data/lib/rocket_job/rocket_job.rb +5 -4
  58. data/lib/rocket_job/server.rb +2 -2
  59. data/lib/rocket_job/server/model.rb +14 -13
  60. data/lib/rocket_job/server/state_machine.rb +1 -2
  61. data/lib/rocket_job/sliced/compressed_slice.rb +4 -4
  62. data/lib/rocket_job/sliced/encrypted_slice.rb +4 -4
  63. data/lib/rocket_job/sliced/input.rb +16 -16
  64. data/lib/rocket_job/sliced/output.rb +2 -2
  65. data/lib/rocket_job/sliced/slice.rb +43 -20
  66. data/lib/rocket_job/sliced/slices.rb +14 -11
  67. data/lib/rocket_job/subscriber.rb +6 -6
  68. data/lib/rocket_job/subscribers/logger.rb +3 -3
  69. data/lib/rocket_job/supervisor.rb +12 -12
  70. data/lib/rocket_job/supervisor/shutdown.rb +7 -7
  71. data/lib/rocket_job/throttle_definition.rb +37 -0
  72. data/lib/rocket_job/throttle_definitions.rb +39 -0
  73. data/lib/rocket_job/version.rb +1 -1
  74. data/lib/rocket_job/worker.rb +116 -34
  75. data/lib/rocket_job/worker_pool.rb +6 -6
  76. data/lib/rocketjob.rb +72 -76
  77. metadata +16 -18
  78. data/lib/rocket_job/extensions/mongoid_5/clients/options.rb +0 -38
  79. data/lib/rocket_job/extensions/mongoid_5/contextual/mongo.rb +0 -64
  80. data/lib/rocket_job/extensions/mongoid_5/factory.rb +0 -13
@@ -13,8 +13,8 @@ module RocketJob
13
13
  #
14
14
  # tabular.render(row)
15
15
  class Tabular
16
- autoload :Input, 'rocket_job/batch/tabular/input'
17
- autoload :Output, 'rocket_job/batch/tabular/output'
16
+ autoload :Input, "rocket_job/batch/tabular/input"
17
+ autoload :Output, "rocket_job/batch/tabular/output"
18
18
 
19
19
  def initialize(map)
20
20
  @map = map
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ require "active_support/concern"
2
2
 
3
3
  module RocketJob
4
4
  module Batch
@@ -53,7 +53,7 @@ module RocketJob
53
53
  input_stream = stream.nil? ? nil : IOStreams.new(stream)
54
54
 
55
55
  if stream && (tabular_input_type == :text)
56
- input_stream.option_or_stream(:encode, encoding: 'UTF-8', cleaner: :printable, replace: '')
56
+ input_stream.option_or_stream(:encode, encoding: "UTF-8", cleaner: :printable, replace: "")
57
57
  end
58
58
 
59
59
  # If an input header is not required, then we don't extract it'
@@ -67,14 +67,14 @@ module RocketJob
67
67
 
68
68
  case tabular_input_mode
69
69
  when :line
70
- parse_header = -> (line) do
70
+ parse_header = lambda do |line|
71
71
  tabular_input.parse_header(line)
72
72
  tabular_input_cleanse_header
73
73
  self.tabular_input_header = tabular_input.header.columns
74
74
  end
75
75
  super(input_stream, on_first: parse_header, stream_mode: :line, **args, &block)
76
76
  when :array, :row
77
- set_header = -> (row) do
77
+ set_header = lambda do |row|
78
78
  tabular_input.header.columns = row
79
79
  tabular_input_cleanse_header
80
80
  self.tabular_input_header = tabular_input.header.columns
@@ -101,19 +101,23 @@ module RocketJob
101
101
  end
102
102
 
103
103
  def tabular_input_render
104
- @rocket_job_input = tabular_input.record_parse(@rocket_job_input) unless tabular_input_header.blank? && tabular_input.header?
104
+ unless tabular_input_header.blank? && tabular_input.header?
105
+ @rocket_job_input = tabular_input.record_parse(@rocket_job_input)
106
+ end
105
107
  end
106
108
 
107
109
  # Cleanse custom input header if supplied.
108
110
  def tabular_input_cleanse_header
109
111
  ignored_columns = tabular_input.header.cleanse!
110
- logger.warn('Stripped out invalid columns from custom header', ignored_columns) unless ignored_columns.empty?
112
+ logger.warn("Stripped out invalid columns from custom header", ignored_columns) unless ignored_columns.empty?
111
113
 
112
114
  self.tabular_input_header = tabular_input.header.columns
113
115
  end
114
116
 
115
117
  def tabular_input_header_present
116
- return if tabular_input_header.present? || !tabular_input.header? || (tabular_input_mode == :hash || tabular_input_mode == :record)
118
+ if tabular_input_header.present? || !tabular_input.header? || (tabular_input_mode == :hash || tabular_input_mode == :record)
119
+ return
120
+ end
117
121
 
118
122
  errors.add(:tabular_input_header, "is required when tabular_input_format is #{tabular_input_format.inspect}")
119
123
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ require "active_support/concern"
2
2
 
3
3
  module RocketJob
4
4
  module Batch
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ require "active_support/concern"
2
2
 
3
3
  module RocketJob
4
4
  module Batch
@@ -31,7 +31,6 @@ module RocketJob
31
31
 
32
32
  included do
33
33
  class_attribute :rocket_job_batch_throttles
34
- self.rocket_job_batch_throttles = []
35
34
  end
36
35
 
37
36
  module ClassMethods
@@ -48,44 +47,26 @@ module RocketJob
48
47
  #
49
48
  # Note: Throttles are executed in the order they are defined.
50
49
  def define_batch_throttle(method_name, filter: :throttle_filter_class)
51
- unless filter.is_a?(Symbol) || filter.is_a?(Proc)
52
- raise(ArgumentError, "Filter for #{method_name} must be a Symbol or Proc")
53
- end
54
- if batch_throttle?(method_name)
55
- raise(ArgumentError, "Cannot define #{method_name} twice, undefine previous throttle first")
56
- end
57
-
58
- self.rocket_job_batch_throttles += [ThrottleDefinition.new(method_name, filter)]
50
+ # Duplicate to prevent modifying parent class throttles
51
+ definitions = rocket_job_batch_throttles ? rocket_job_batch_throttles.dup : ThrottleDefinitions.new
52
+ definitions.add(method_name, filter)
53
+ self.rocket_job_batch_throttles = definitions
59
54
  end
60
55
 
61
56
  # Undefine a previously defined throttle
62
57
  def undefine_batch_throttle(method_name)
63
- rocket_job_batch_throttles.delete_if { |throttle| throttle.method_name == method_name }
58
+ return unless rocket_job_batch_throttles
59
+
60
+ definitions = rocket_job_batch_throttles.dup
61
+ definitions.remove(method_name)
62
+ self.rocket_job_batch_throttles = definitions
64
63
  end
65
64
 
66
65
  # Has a throttle been defined?
67
66
  def batch_throttle?(method_name)
68
- rocket_job_batch_throttles.any? { |throttle| throttle.method_name == method_name }
67
+ rocket_job_batch_throttles.exist?(method_name)
69
68
  end
70
69
  end
71
-
72
- private
73
-
74
- ThrottleDefinition = Struct.new(:method_name, :filter)
75
-
76
- # Returns the matching filter, or nil if no throttles were triggered.
77
- def rocket_job_batch_evaluate_throttles(slice)
78
- rocket_job_batch_throttles.each do |throttle|
79
- throttle_exceeded = method(throttle.method_name).arity == 0 ? send(throttle.method_name) : send(throttle.method_name, slice)
80
- next unless throttle_exceeded
81
-
82
- logger.debug { "Batch Throttle: #{throttle.method_name} has been exceeded. #{self.class.name}:#{id}" }
83
- filter = throttle.filter
84
- return filter.is_a?(Proc) ? filter.call(self) : send(filter)
85
- end
86
- nil
87
- end
88
-
89
70
  end
90
71
  end
91
72
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ require "active_support/concern"
2
2
 
3
3
  module RocketJob
4
4
  module Batch
@@ -9,7 +9,7 @@ module RocketJob
9
9
  # include RocketJob::Batch
10
10
  #
11
11
  # # Maximum number of slices to process at the same time for each running instance.
12
- # self.throttle_running_slices = 25
12
+ # self.throttle_running_workers = 25
13
13
  #
14
14
  # def perform(record)
15
15
  # # ....
@@ -28,28 +28,31 @@ module RocketJob
28
28
  # 0 or nil : No limits in place
29
29
  #
30
30
  # Default: nil
31
- module ThrottleRunningSlices
31
+ module ThrottleRunningWorkers
32
32
  extend ActiveSupport::Concern
33
33
 
34
34
  included do
35
- field :throttle_running_slices, type: Integer, class_attribute: true, user_editable: true, copy_on_restart: true
35
+ field :throttle_running_workers, type: Integer, class_attribute: true, user_editable: true, copy_on_restart: true
36
36
 
37
- validates :throttle_running_slices, numericality: {greater_than_or_equal_to: 0}, allow_nil: true
37
+ validates :throttle_running_workers, numericality: {greater_than_or_equal_to: 0}, allow_nil: true
38
38
 
39
- define_batch_throttle :throttle_running_slices_exceeded?, filter: :throttle_filter_id
39
+ define_batch_throttle :throttle_running_workers_exceeded?, filter: :throttle_filter_id
40
+
41
+ # Deprecated. For backward compatibility.
42
+ alias_method :throttle_running_slices, :throttle_running_workers
43
+ alias_method :throttle_running_slices=, :throttle_running_workers=
40
44
  end
41
45
 
42
46
  private
43
47
 
44
48
  # Returns [Boolean] whether the throttle for this job has been exceeded
45
- def throttle_running_slices_exceeded?(slice)
46
- return unless throttle_running_slices&.positive?
49
+ def throttle_running_workers_exceeded?(slice)
50
+ return unless throttle_running_workers&.positive?
47
51
 
48
52
  input.running.with(read: {mode: :primary}) do |conn|
49
- conn.where(:id.ne => slice.id).count >= throttle_running_slices
53
+ conn.where(:id.ne => slice.id).count >= throttle_running_workers
50
54
  end
51
55
  end
52
-
53
56
  end
54
57
  end
55
58
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ require "active_support/concern"
2
2
 
3
3
  module RocketJob
4
4
  module Batch
@@ -16,10 +16,10 @@ module RocketJob
16
16
 
17
17
  # Processes records in each available slice for this job. Slices are processed
18
18
  # one at a time to allow for concurrent calls to this method to increase
19
- # throughput. Processing will continue until there are no more jobs available
19
+ # throughput. Processing will continue until there are no more slices available
20
20
  # for this job.
21
21
  #
22
- # Returns [true|false] whether this job should be excluded from the next lookup
22
+ # Returns [true|false] whether any work was performed.
23
23
  #
24
24
  # Slices are destroyed after their records are successfully processed
25
25
  #
@@ -33,36 +33,34 @@ module RocketJob
33
33
  # Mongo connection failure occurs.
34
34
  #
35
35
  # Thread-safe, can be called by multiple threads at the same time
36
- def rocket_job_work(worker, re_raise_exceptions = false, filter = {})
37
- raise 'Job must be started before calling #rocket_job_work' unless running?
36
+ def rocket_job_work(worker, re_raise_exceptions = false)
37
+ raise "Job must be started before calling #rocket_job_work" unless running?
38
+
38
39
  start_time = Time.now
39
40
  if sub_state != :processing
40
- rocket_job_handle_callbacks(worker, re_raise_exceptions)
41
+ fail_on_exception!(re_raise_exceptions) { rocket_job_batch_callbacks(worker) }
41
42
  return false unless running?
42
43
  end
43
44
 
44
- while !worker.shutdown?
45
- if slice = input.next_slice(worker.name)
46
- # Grab a slice before checking the throttle to reduce concurrency race condition.
47
- if new_filter = rocket_job_batch_evaluate_throttles(slice)
48
- # Restore retrieved slice so that other workers can process it later.
49
- slice.set(worker_name: nil, state: :queued, started_at: nil)
50
- self.class.send(:rocket_job_merge_filter, filter, new_filter)
45
+ SemanticLogger.named_tagged(job: id.to_s) do
46
+ until worker.shutdown?
47
+ if slice = input.next_slice(worker.name)
48
+ # Grab a slice before checking the throttle to reduce concurrency race condition.
49
+ return true if slice.fail_on_exception!(re_raise_exceptions) { rocket_job_batch_throttled?(slice, worker) }
50
+ next if slice.failed?
51
+
52
+ slice.fail_on_exception!(re_raise_exceptions) { rocket_job_process_slice(slice) }
53
+ elsif record_count && rocket_job_batch_complete?(worker.name)
54
+ return false
55
+ else
56
+ logger.debug "No more work available for this job"
57
+ worker.add_to_current_filter(throttle_filter_id)
51
58
  return true
52
59
  end
53
60
 
54
- SemanticLogger.named_tagged(slice: slice.id.to_s) do
55
- rocket_job_process_slice(slice, re_raise_exceptions)
56
- end
57
- else
58
- break if record_count && rocket_job_batch_complete?(worker.name)
59
- logger.debug 'No more work available for this job'
60
- self.class.send(:rocket_job_merge_filter, filter, throttle_filter_id)
61
- return true
61
+ # Allow new jobs with a higher priority to interrupt this job
62
+ break if (Time.now - start_time) >= Config.re_check_seconds
62
63
  end
63
-
64
- # Allow new jobs with a higher priority to interrupt this job
65
- break if (Time.now - start_time) >= Config.re_check_seconds
66
64
  end
67
65
  false
68
66
  end
@@ -76,27 +74,26 @@ module RocketJob
76
74
  #
77
75
  # Note: The slice will be removed from processing when this method completes
78
76
  def work_first_slice(&block)
79
- raise '#work_first_slice can only be called from within before_batch callbacks' unless sub_state == :before
80
- # TODO Make these settings configurable
77
+ raise "#work_first_slice can only be called from within before_batch callbacks" unless sub_state == :before
78
+
79
+ # TODO: Make these settings configurable
81
80
  count = 0
82
81
  wait_seconds = 5
83
- while (slice = input.first).nil?
82
+ while input.first.nil?
84
83
  break if count > 10
84
+
85
85
  logger.info "First slice has not arrived yet, sleeping for #{wait_seconds} seconds"
86
86
  sleep wait_seconds
87
87
  count += 1
88
88
  end
89
89
 
90
- if slice = input.first
91
- SemanticLogger.named_tagged(slice: slice.id.to_s) do
92
- # TODO Persist that the first slice is being processed by this worker
93
- slice.start
94
- rocket_job_process_slice(slice, true, &block)
95
- end
96
- else
97
- # No records processed
98
- 0
99
- end
90
+ slice = input.first
91
+ # No records processed
92
+ return 0 unless slice
93
+
94
+ # TODO: Persist that the first slice is being processed by this worker
95
+ slice.start
96
+ rocket_job_process_slice(slice, &block)
100
97
  end
101
98
 
102
99
  # Returns [Array<ActiveWorker>] All workers actively working on this job
@@ -119,50 +116,73 @@ module RocketJob
119
116
 
120
117
  private
121
118
 
119
+ def rocket_job_batch_throttled?(slice, worker)
120
+ filter = self.class.rocket_job_batch_throttles.matching_filter(self, slice)
121
+ return false unless filter
122
+
123
+ # Restore retrieved slice so that other workers can process it later.
124
+ slice.set(worker_name: nil, state: :queued, started_at: nil)
125
+ worker.add_to_current_filter(filter)
126
+ true
127
+ end
128
+
122
129
  # Process a single slice from Mongo
123
130
  # Once the slice has been successfully processed it will be removed from the input collection
124
131
  # Returns [Integer] the number of records successfully processed
125
- def rocket_job_process_slice(slice, re_raise_exceptions)
126
- slice_record_number = 0
132
+ def rocket_job_process_slice(slice)
133
+ # TODO: Skip records already processed
127
134
  @rocket_job_record_number = slice.first_record_number || 0
128
135
  @rocket_job_slice = slice
129
- run_callbacks :slice do
136
+
137
+ processed_records = 0
138
+ run_callbacks(:slice) do
139
+ # Allow before_slice callbacks to fail, complete or abort this slice.
140
+ return 0 unless running?
141
+
130
142
  RocketJob::Sliced::Writer::Output.collect(self, slice) do |writer|
131
143
  slice.each do |record|
132
- slice_record_number += 1
133
144
  SemanticLogger.named_tagged(record: @rocket_job_record_number) do
134
- if _perform_callbacks.empty?
135
- @rocket_job_output = block_given? ? yield(record) : perform(record)
136
- else
137
- # Allows @rocket_job_input to be modified by before/around callbacks
138
- @rocket_job_input = record
139
- # Allow callbacks to fail, complete or abort the job
140
- if running?
141
- if block_given?
142
- run_callbacks(:perform) { @rocket_job_output = yield(@rocket_job_input) }
143
- else
144
- # Allows @rocket_job_output to be modified by after/around callbacks
145
- run_callbacks(:perform) { @rocket_job_output = perform(@rocket_job_input) }
146
- end
147
- end
148
- end
149
- writer << @rocket_job_output
145
+ writer << rocket_job_batch_perform(slice, record)
146
+ processed_records += 1
150
147
  end
151
- # JRuby says self.rocket_job_record_number= is private and cannot be accessed
148
+ # JRuby thinks self.rocket_job_record_number= is private and cannot be accessed
152
149
  @rocket_job_record_number += 1
153
150
  end
154
151
  end
155
- @rocket_job_input = @rocket_job_slice = @rocket_job_output = nil
152
+ @rocket_job_slice = nil
153
+ @rocket_job_record_number = nil
156
154
  end
157
155
 
158
156
  # On successful completion remove the slice from the input queue
159
- # TODO Option to complete slice instead of destroying it to retain input data
157
+ # TODO: Add option to complete slice instead of destroying it to retain input data.
160
158
  slice.destroy
161
- slice_record_number
162
- rescue Exception => exc
163
- slice.fail!(exc, slice_record_number)
164
- raise exc if re_raise_exceptions
165
- slice_record_number > 0 ? slice_record_number - 1 : 0
159
+ processed_records
160
+ end
161
+
162
+ # Perform a single record within the current slice.
163
+ def rocket_job_batch_perform(slice, record)
164
+ slice.processing_record_number ||= 0
165
+ slice.processing_record_number += 1
166
+
167
+ return block_given? ? yield(record) : perform(record) if _perform_callbacks.empty?
168
+
169
+ # @rocket_job_input and @rocket_job_output can be modified by before/around callbacks
170
+ @rocket_job_input = record
171
+ @rocket_job_output = nil
172
+
173
+ run_callbacks(:perform) do
174
+ @rocket_job_output =
175
+ if block_given?
176
+ yield(@rocket_job_input)
177
+ else
178
+ perform(@rocket_job_input)
179
+ end
180
+ end
181
+
182
+ @rocket_job_input = nil
183
+ result = @rocket_job_output
184
+ @rocket_job_output = nil
185
+ result
166
186
  end
167
187
 
168
188
  # Checks for completion and runs after_batch if defined
@@ -174,7 +194,7 @@ module RocketJob
174
194
  # Only failed slices left?
175
195
  input_count = input.count
176
196
  failed_count = input.failed.count
177
- if (failed_count > 0) && (input_count == failed_count)
197
+ if failed_count.positive? && (input_count == failed_count)
178
198
  # Reload to pull in any counters or other data that was modified.
179
199
  reload unless new_record?
180
200
  if may_fail?
@@ -185,9 +205,9 @@ module RocketJob
185
205
  result = self.class.with(write: {w: 1}) do |query|
186
206
  query.
187
207
  where(id: id, state: :running, sub_state: :processing).
188
- update({'$set' => {state: :failed, worker_name: worker_name}})
208
+ update({"$set" => {state: :failed, worker_name: worker_name}})
189
209
  end
190
- fail_job = false unless result.modified_count > 0
210
+ fail_job = false unless result.modified_count.positive?
191
211
  end
192
212
  if fail_job
193
213
  message = "#{failed_count} slices failed to process"
@@ -199,7 +219,7 @@ module RocketJob
199
219
  end
200
220
 
201
221
  # Any work left?
202
- return false if input_count > 0
222
+ return false if input_count.positive?
203
223
 
204
224
  # If the job was not saved to the queue, do not save any changes
205
225
  if new_record?
@@ -212,12 +232,12 @@ module RocketJob
212
232
  result = self.class.with(write: {w: 1}) do |query|
213
233
  query.
214
234
  where(id: id, state: :running, sub_state: :processing).
215
- update('$set' => {sub_state: :after, worker_name: worker_name})
235
+ update("$set" => {sub_state: :after, worker_name: worker_name})
216
236
  end
217
237
 
218
238
  # Reload to pull in any counters or other data that was modified.
219
239
  reload
220
- if result.modified_count > 0
240
+ if result.modified_count.positive?
221
241
  rocket_job_batch_run_after_callbacks(false)
222
242
  else
223
243
  # Repeat cleanup in case this worker was still running when the job was aborted
@@ -233,7 +253,7 @@ module RocketJob
233
253
  self.sub_state = :before
234
254
  save! unless new_record? || destroyed?
235
255
  logger.measure_info(
236
- 'before_batch',
256
+ "before_batch",
237
257
  metric: "#{self.class.name}/before_batch",
238
258
  log_exception: :full,
239
259
  on_exception_level: :error,
@@ -253,7 +273,7 @@ module RocketJob
253
273
  self.sub_state = :after
254
274
  save! if save_before && !new_record? && !destroyed?
255
275
  logger.measure_info(
256
- 'after_batch',
276
+ "after_batch",
257
277
  metric: "#{self.class.name}/after_batch",
258
278
  log_exception: :full,
259
279
  on_exception_level: :error,
@@ -269,20 +289,17 @@ module RocketJob
269
289
  end
270
290
  end
271
291
 
272
- # Handle before and after callbacks
273
- def rocket_job_handle_callbacks(worker, re_raise_exceptions)
274
- rocket_job_fail_on_exception!(worker.name, re_raise_exceptions) do
275
- # If this is the first worker to pickup this job
276
- if sub_state == :before
277
- rocket_job_batch_run_before_callbacks
278
- # Check for 0 record jobs
279
- rocket_job_batch_complete?(worker.name) if running?
280
- elsif sub_state == :after
281
- rocket_job_batch_run_after_callbacks
282
- end
292
+ # Run Batch before and after callbacks
293
+ def rocket_job_batch_callbacks(worker)
294
+ # If this is the first worker to pickup this job
295
+ if sub_state == :before
296
+ rocket_job_batch_run_before_callbacks
297
+ # Check for 0 record jobs
298
+ rocket_job_batch_complete?(worker.name) if running?
299
+ elsif sub_state == :after
300
+ rocket_job_batch_run_after_callbacks
283
301
  end
284
302
  end
285
-
286
303
  end
287
304
  end
288
305
  end