maintenance_tasks 2.12.0 → 2.13.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d307d92f96c1d1975cc3fbefcddf6ec2e11086097437b63594090c5bc524eea8
4
- data.tar.gz: 9176d7a34c4a54f450601ea2748a88b1a9f134c9e416e97978e613bf3fbf1538
3
+ metadata.gz: 8402f1f4b8919e892a6334373ad397d49b5c6c78893f2f107b990b90653435d1
4
+ data.tar.gz: 1459d5b92233a1196aeb83c80bec9da525f04e975a50f6a415cdcd8dc647bd59
5
5
  SHA512:
6
- metadata.gz: 87d37b437e518c0398023335fe88cb0c7829387142873eeb01aa713df04f397e7711491f0ace1a32baae20f4f1a613313c59e95696deef73d6ecfad24b6fb267
7
- data.tar.gz: b0c5fce124651391b77b8f2e5d91f8eb84c0415744fda8429b11a64b730a2e1ef02335c05685a98946fffdfd5042aa3b6f2a23a645a454613acd364af612b09d
6
+ metadata.gz: 3dff16b85a650f4d73cf79df20267d1278b1181f2ba6717742581909ebfd39145dfdd9b9cf1453edaa785474fb6f7dda87af2bad534e6398bf010945b02f2da3
7
+ data.tar.gz: c7b75c1edc684fad66c5080ee3642fe469038e1f4ab2329ead0fd3c65e5f0ca2a940250dc988658dce672e2de0d056741b9a317310afa23165ba27794722ce1d
data/README.md CHANGED
@@ -1027,7 +1027,7 @@ be placed in a `maintenance_tasks.rb` initializer.
1027
1027
  Exceptions raised while a Task is performing are rescued and information about
1028
1028
  the error is persisted and visible in the UI.
1029
1029
 
1030
- Errors are also sent to the `Rails.error.reporter`, which can be configured by
1030
+ Errors are also sent to `Rails.error.report`, which can be configured by
1031
1031
  your application. See the [Error Reporting in Rails
1032
1032
  Applications][rails-error-reporting] guide for more details.
1033
1033
 
@@ -1042,11 +1042,42 @@ Reports to the error reporter will contain the following data:
1042
1042
  * `tick_count`: The tick count at the time of the error
1043
1043
  * `errored_element`: The element, if any, that was being processed when the
1044
1044
  * `source`: This will be `maintenance-tasks`
1045
+ * `handled`: the value of `MaintenanceTasks.report_errors_as_handled` (default `true`, see below)
1045
1046
 
1046
1047
  Note that `context` may be empty if the Task produced an error before any
1047
1048
  context could be gathered (for example, if deserializing the job to process your
1048
1049
  Task failed).
1049
1050
 
1051
+ Here's an example custom subscriber to the Rails error reporter for integrating
1052
+ with an exception monitoring service (Bugsnag):
1053
+
1054
+ ```ruby
1055
+ # config/initializers/maintenance_tasks.rb
1056
+ MaintenanceTasks.report_errors_as_handled = false
1057
+
1058
+ class MaintenanceTasksErrorSubscriber
1059
+ def report(error, handled:, severity:, context:, source: nil)
1060
+ return unless source == "maintenance-tasks"
1061
+
1062
+ unless handled
1063
+ Bugsnag.notify(error) do |notification|
1064
+ notification.add_metadata(:task, context)
1065
+ end
1066
+ else
1067
+ Rails.logger.info(error)
1068
+ end
1069
+ end
1070
+ end
1071
+
1072
+ Rails.error.subscribe(MaintenanceTasksErrorSubscriber.new)
1073
+ ```
1074
+
1075
+ `MaintenanceTasks.report_errors_as_handled` determines the value for `handled` in this example.
1076
+ By default (for backwards compatibility) this is `true`.
1077
+ Setting this to `false` provides more accurate error reporting as it allows to distinguish between
1078
+ expected (e.g., via `report_on`) and unexpected errors in error subscribers.
1079
+ `false` will be the default in v3.0.
1080
+
1050
1081
  #### Reporting errors during iteration
1051
1082
 
1052
1083
  By default, errors raised during task iteration will be raised to the
@@ -1236,6 +1267,42 @@ The value for `MaintenanceTasks.stuck_task_duration` must be an
1236
1267
  `ActiveSupport::Duration`. If no value is specified, it will default to 5
1237
1268
  minutes.
1238
1269
 
1270
+ #### Configure status reload frequency
1271
+
1272
+ `MaintenanceTasks.status_reload_frequency` can be configured to specify how often
1273
+ the run status should be reloaded during iteration. By default, the status is
1274
+ reloaded every second, but this can be increased to improve performance. Note that increasing the reload interval impacts how quickly
1275
+ your task will stop if it is paused or interrupted.
1276
+
1277
+ ```ruby
1278
+ # config/initializers/maintenance_tasks.rb
1279
+ MaintenanceTasks.status_reload_frequency = 10.seconds # Reload status every 10 seconds
1280
+ ```
1281
+
1282
+ Individual tasks can also override this setting using the `reload_status_every` method:
1283
+
1284
+ ```ruby
1285
+ # app/tasks/maintenance/update_posts_task.rb
1286
+
1287
+ module Maintenance
1288
+ class UpdatePostsTask < MaintenanceTasks::Task
1289
+ # Reload status every 5 seconds instead of the global default
1290
+ reload_status_every(5.seconds)
1291
+
1292
+ def collection
1293
+ Post.all
1294
+ end
1295
+
1296
+ def process(post)
1297
+ post.update!(content: "New content!")
1298
+ end
1299
+ end
1300
+ end
1301
+ ```
1302
+
1303
+ This optimization can significantly reduce database queries, especially for short iterations.
1304
+ This is especially useful if the task doesn't need to check for cancellation/pausing very often.
1305
+
1239
1306
  #### Metadata
1240
1307
 
1241
1308
  `MaintenanceTasks.metadata` can be configured to specify a proc from which to
@@ -13,9 +13,15 @@ module MaintenanceTasks
13
13
  # <style> tag in app/views/layouts/maintenance_tasks/application.html.erb
14
14
  "'sha256-WHHDQLdkleXnAN5zs0GDXC5ls41CHUaVsJtVpaNx+EM='",
15
15
  )
16
+ capybara_lockstep_scripts = [
17
+ "'sha256-1AoN3ZtJC5OvqkMgrYvhZjp4kI8QjJjO7TAyKYiDw+U='",
18
+ "'sha256-QVSzZi6ZsX/cu4h+hIs1iVivG1BxUmJggiEsGDIXBG0='", # with debug on
19
+ ] if defined?(Capybara::Lockstep)
16
20
  policy.script_src_elem(
17
21
  # <script> tag in app/views/layouts/maintenance_tasks/application.html.erb
18
22
  "'sha256-NiHKryHWudRC2IteTqmY9v1VkaDUA/5jhgXkMTkgo2w='",
23
+ # <script> tag for capybara-lockstep
24
+ *capybara_lockstep_scripts,
19
25
  )
20
26
 
21
27
  policy.require_trusted_types_for # disable because we use new DOMParser().parseFromString
@@ -101,7 +101,8 @@ module MaintenanceTasks
101
101
  throw(:abort, :skip_complete_callbacks) if @run.stopping?
102
102
  task_iteration(input)
103
103
  @ticker.tick
104
- @run.reload_status
104
+
105
+ reload_run_status
105
106
  end
106
107
 
107
108
  def task_iteration(input)
@@ -127,6 +128,8 @@ module MaintenanceTasks
127
128
  @ticker = Ticker.new(MaintenanceTasks.ticker_delay) do |ticks, duration|
128
129
  @run.persist_progress(ticks, duration)
129
130
  end
131
+
132
+ @last_status_reload = nil
130
133
  end
131
134
 
132
135
  def on_start
@@ -190,11 +193,28 @@ module MaintenanceTasks
190
193
  if MaintenanceTasks.instance_variable_get(:@error_handler)
191
194
  errored_element = task_context.delete(:errored_element)
192
195
  MaintenanceTasks.error_handler.call(error, task_context.except(:run_id, :tick_count), errored_element)
193
- elsif Rails.gem_version >= Gem::Version.new("7.1")
194
- Rails.error.report(error, context: task_context, source: "maintenance-tasks")
195
196
  else
196
- Rails.error.report(error, handled: true, context: task_context)
197
+ Rails.error.report(
198
+ error,
199
+ handled: MaintenanceTasks.report_errors_as_handled,
200
+ context: task_context,
201
+ source: "maintenance-tasks",
202
+ )
197
203
  end
198
204
  end
205
+
206
+ def reload_run_status
207
+ return unless should_reload_status?
208
+
209
+ @run.reload_status
210
+ @last_status_reload = Time.now
211
+ end
212
+
213
+ def should_reload_status?
214
+ return true if @last_status_reload.nil?
215
+
216
+ time_since_last_reload = Time.now - @last_status_reload
217
+ time_since_last_reload >= @task.status_reload_frequency
218
+ end
199
219
  end
200
220
  end
@@ -44,15 +44,9 @@ module MaintenanceTasks
44
44
 
45
45
  attr_readonly :task_name
46
46
 
47
- if Rails.gem_version >= Gem::Version.new("7.1.alpha")
48
- serialize :backtrace, coder: YAML
49
- serialize :arguments, coder: JSON
50
- serialize :metadata, coder: JSON
51
- else
52
- serialize :backtrace
53
- serialize :arguments, JSON
54
- serialize :metadata, JSON
55
- end
47
+ serialize :backtrace, coder: YAML
48
+ serialize :arguments, coder: JSON
49
+ serialize :metadata, coder: JSON
56
50
 
57
51
  scope :active, -> { where(status: ACTIVE_STATUSES) }
58
52
  scope :completed, -> { where(status: COMPLETED_STATUSES) }
@@ -79,11 +73,10 @@ module MaintenanceTasks
79
73
  # Rescues and retries status transition if an ActiveRecord::StaleObjectError
80
74
  # is encountered.
81
75
  def enqueued!
82
- status_will_change!
83
- super
84
- rescue ActiveRecord::StaleObjectError
85
- reload_status
86
- retry
76
+ with_stale_object_retry do
77
+ status_will_change!
78
+ super
79
+ end
87
80
  end
88
81
 
89
82
  CALLBACKS_TRANSITION = {
@@ -92,23 +85,39 @@ module MaintenanceTasks
92
85
  paused: :pause,
93
86
  succeeded: :complete,
94
87
  }.transform_keys(&:to_s)
95
- private_constant :CALLBACKS_TRANSITION
88
+
89
+ DELAYS_PER_ATTEMPT = [0.1, 0.2, 0.4, 0.8, 1.6]
90
+ MAX_RETRIES = DELAYS_PER_ATTEMPT.size
91
+
92
+ private_constant :CALLBACKS_TRANSITION, :DELAYS_PER_ATTEMPT, :MAX_RETRIES
96
93
 
97
94
  # Saves the run, persisting the transition of its status, and all other
98
95
  # changes to the object.
99
96
  def persist_transition
100
- save!
97
+ retry_count = 0
98
+ begin
99
+ save!
100
+ rescue ActiveRecord::StaleObjectError
101
+ if retry_count < MAX_RETRIES
102
+ sleep(DELAYS_PER_ATTEMPT[retry_count])
103
+ retry_count += 1
104
+
105
+ success = succeeded?
106
+ reload_status
107
+ if success
108
+ self.status = :succeeded
109
+ else
110
+ job_shutdown
111
+ end
112
+
113
+ retry
114
+ else
115
+ raise
116
+ end
117
+ end
118
+
101
119
  callback = CALLBACKS_TRANSITION[status]
102
120
  run_task_callbacks(callback) if callback
103
- rescue ActiveRecord::StaleObjectError
104
- success = succeeded?
105
- reload_status
106
- if success
107
- self.status = :succeeded
108
- else
109
- job_shutdown
110
- end
111
- retry
112
121
  end
113
122
 
114
123
  # Increments +tick_count+ by +number_of_ticks+ and +time_running+ by
@@ -126,29 +135,23 @@ module MaintenanceTasks
126
135
  time_running: duration,
127
136
  touch: true,
128
137
  )
129
- if locking_enabled?
130
- locking_column = self.class.locking_column
131
- self[locking_column] += 1
132
- clear_attribute_change(locking_column)
133
- end
134
138
  end
135
139
 
136
140
  # Marks the run as errored and persists the error data.
137
141
  #
138
142
  # @param error [StandardError] the Error being persisted.
139
143
  def persist_error(error)
140
- self.started_at ||= Time.now
141
- update!(
142
- status: :errored,
143
- error_class: truncate(:error_class, error.class.name),
144
- error_message: truncate(:error_message, error.message),
145
- backtrace: MaintenanceTasks.backtrace_cleaner.clean(error.backtrace),
146
- ended_at: Time.now,
147
- )
144
+ with_stale_object_retry do
145
+ self.started_at ||= Time.now
146
+ update!(
147
+ status: :errored,
148
+ error_class: truncate(:error_class, error.class.name),
149
+ error_message: truncate(:error_message, error.message),
150
+ backtrace: MaintenanceTasks.backtrace_cleaner.clean(error.backtrace),
151
+ ended_at: Time.now,
152
+ )
153
+ end
148
154
  run_error_callback
149
- rescue ActiveRecord::StaleObjectError
150
- reload_status
151
- retry
152
155
  end
153
156
 
154
157
  # Refreshes the status and lock version attributes on the Active Record
@@ -241,11 +244,8 @@ module MaintenanceTasks
241
244
  # is encountered.
242
245
  def running
243
246
  if locking_enabled?
244
- begin
247
+ with_stale_object_retry do
245
248
  running! unless stopping?
246
- rescue ActiveRecord::StaleObjectError
247
- reload_status
248
- retry
249
249
  end
250
250
  else
251
251
  # Preserve swap-and-replace solution for data races until users
@@ -268,11 +268,11 @@ module MaintenanceTasks
268
268
  # @param count [Integer] the total iterations to be performed, as
269
269
  # specified by the Task.
270
270
  def start(count)
271
- update!(started_at: Time.now, tick_total: count)
271
+ with_stale_object_retry do
272
+ update!(started_at: Time.now, tick_total: count)
273
+ end
274
+
272
275
  task.run_callbacks(:start)
273
- rescue ActiveRecord::StaleObjectError
274
- reload_status
275
- retry
276
276
  end
277
277
 
278
278
  # Handles transitioning the status on a Run when the job shuts down.
@@ -307,16 +307,15 @@ module MaintenanceTasks
307
307
  # minutes ago, it will transition to cancelled, and the ended_at timestamp
308
308
  # will be updated.
309
309
  def cancel
310
- if paused? || stuck?
311
- self.status = :cancelled
312
- self.ended_at = Time.now
313
- persist_transition
314
- else
315
- cancelling!
310
+ with_stale_object_retry do
311
+ if paused? || stuck?
312
+ self.status = :cancelled
313
+ self.ended_at = Time.now
314
+ persist_transition
315
+ else
316
+ cancelling!
317
+ end
316
318
  end
317
- rescue ActiveRecord::StaleObjectError
318
- reload_status
319
- retry
320
319
  end
321
320
 
322
321
  # Marks a Run as pausing.
@@ -327,15 +326,14 @@ module MaintenanceTasks
327
326
  # Rescues and retries status transition if an ActiveRecord::StaleObjectError
328
327
  # is encountered.
329
328
  def pause
330
- if stuck?
331
- self.status = :paused
332
- persist_transition
333
- else
334
- pausing!
329
+ with_stale_object_retry do
330
+ if stuck?
331
+ self.status = :paused
332
+ persist_transition
333
+ else
334
+ pausing!
335
+ end
335
336
  end
336
- rescue ActiveRecord::StaleObjectError
337
- reload_status
338
- retry
339
337
  end
340
338
 
341
339
  # Returns whether a Run is stuck, which is defined as having a status of
@@ -499,5 +497,26 @@ module MaintenanceTasks
499
497
  Rails.application.config.filter_parameters + task.masked_arguments,
500
498
  )
501
499
  end
500
+
501
+ def with_stale_object_retry(retry_count = 0)
502
+ yield
503
+ rescue ActiveRecord::StaleObjectError
504
+ if retry_count < MAX_RETRIES
505
+ sleep(stale_object_retry_delay(retry_count))
506
+ retry_count += 1
507
+ reload_status
508
+
509
+ retry
510
+ else
511
+ raise
512
+ end
513
+ end
514
+
515
+ def stale_object_retry_delay(retry_count)
516
+ delay = DELAYS_PER_ATTEMPT[retry_count]
517
+ # Add jitter (±25% randomization) to prevent thundering herd
518
+ jitter = delay * 0.25
519
+ delay + (rand * 2 - 1) * jitter
520
+ end
502
521
  end
503
522
  end
@@ -33,6 +33,12 @@ module MaintenanceTasks
33
33
  # @api private
34
34
  class_attribute :masked_arguments, default: []
35
35
 
36
+ # The frequency at which to reload the run status during iteration.
37
+ # Defaults to the global MaintenanceTasks.status_reload_frequency setting.
38
+ #
39
+ # @api private
40
+ class_attribute :status_reload_frequency, default: MaintenanceTasks.status_reload_frequency
41
+
36
42
  define_callbacks :start, :complete, :error, :cancel, :pause, :interrupt
37
43
 
38
44
  attr_accessor :metadata
@@ -167,6 +173,15 @@ module MaintenanceTasks
167
173
  self.masked_arguments += attributes
168
174
  end
169
175
 
176
+ # Configure how frequently the run status should be reloaded during iteration.
177
+ # Use this to reduce database queries when processing large collections.
178
+ #
179
+ # @param frequency [ActiveSupport::Duration, Numeric] reload status every N seconds (default: 1 second).
180
+ # Setting this to 10.seconds means status will be reloaded every 10 seconds.
181
+ def reload_status_every(frequency)
182
+ self.status_reload_frequency = frequency
183
+ end
184
+
170
185
  # Initialize a callback to run after the task starts.
171
186
  #
172
187
  # @param filter_list apply filters to the callback
@@ -220,14 +235,10 @@ module MaintenanceTasks
220
235
  #
221
236
  # @param exceptions list of exceptions to rescue and report
222
237
  # @param report_options [Hash] optionally, supply additional options for `Rails.error.report`.
223
- # By default: <code>{ source: "maintenance_tasks" }</code> or (Rails <v7.1) <code>{ handled: true }</code>.
238
+ # By default: <code>{ handled: true, source: "maintenance-tasks" }</code>.
224
239
  def report_on(*exceptions, **report_options)
225
240
  rescue_from(*exceptions) do |exception|
226
- if Rails.gem_version >= Gem::Version.new("7.1")
227
- Rails.error.report(exception, source: "maintenance_tasks", **report_options)
228
- else
229
- Rails.error.report(exception, handled: true, **report_options)
230
- end
241
+ Rails.error.report(exception, source: "maintenance-tasks", **report_options)
231
242
  end
232
243
  end
233
244
 
@@ -3,6 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <%= capybara_lockstep if defined?(Capybara::Lockstep) %>
6
7
 
7
8
  <title>
8
9
  <% if content_for?(:page_title) %>
@@ -99,6 +100,6 @@
99
100
 
100
101
  <%= yield %>
101
102
  </div>
102
- </div>
103
+ </section>
103
104
  </body>
104
105
  </html>
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreateMaintenanceTasksRuns < ActiveRecord::Migration[6.0]
3
+ class CreateMaintenanceTasksRuns < ActiveRecord::Migration[7.0]
4
4
  def change
5
5
  create_table(:maintenance_tasks_runs, id: primary_key_type) do |t|
6
6
  t.string(:task_name, null: false)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ChangeCursorToString < ActiveRecord::Migration[6.0]
3
+ class ChangeCursorToString < ActiveRecord::Migration[7.0]
4
4
  # This migration will clear all existing data in the cursor column with MySQL.
5
5
  # Ensure no Tasks are paused when this migration is deployed, or they will be resumed from the start.
6
6
  # Running tasks are able to gracefully handle this change, even if interrupted.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class RemoveIndexOnTaskName < ActiveRecord::Migration[6.0]
3
+ class RemoveIndexOnTaskName < ActiveRecord::Migration[7.0]
4
4
  def up
5
5
  change_table(:maintenance_tasks_runs) do |t|
6
6
  t.remove_index(:task_name)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddArgumentsToMaintenanceTasksRuns < ActiveRecord::Migration[6.0]
3
+ class AddArgumentsToMaintenanceTasksRuns < ActiveRecord::Migration[7.0]
4
4
  def change
5
5
  add_column(:maintenance_tasks_runs, :arguments, :text)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddLockVersionToMaintenanceTasksRuns < ActiveRecord::Migration[6.0]
3
+ class AddLockVersionToMaintenanceTasksRuns < ActiveRecord::Migration[7.0]
4
4
  def change
5
5
  add_column(
6
6
  :maintenance_tasks_runs,
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ChangeRunsTickColumnsToBigints < ActiveRecord::Migration[6.0]
3
+ class ChangeRunsTickColumnsToBigints < ActiveRecord::Migration[7.0]
4
4
  def up
5
5
  change_table(:maintenance_tasks_runs, bulk: true) do |t|
6
6
  t.change(:tick_count, :bigint)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddIndexOnTaskNameAndStatusToRuns < ActiveRecord::Migration[6.0]
3
+ class AddIndexOnTaskNameAndStatusToRuns < ActiveRecord::Migration[7.0]
4
4
  def change
5
5
  remove_index(
6
6
  :maintenance_tasks_runs,
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddMetadataToRuns < ActiveRecord::Migration[6.0]
3
+ class AddMetadataToRuns < ActiveRecord::Migration[7.0]
4
4
  def change
5
5
  add_column(:maintenance_tasks_runs, :metadata, :text)
6
6
  end
@@ -21,10 +21,8 @@ module MaintenanceTasks
21
21
  MaintenanceTasks.backtrace_cleaner = Rails.backtrace_cleaner
22
22
  end
23
23
 
24
- if Rails.gem_version >= Gem::Version.new("7.1")
25
- initializer "maintenance_tasks.deprecator" do
26
- Rails.application.deprecators[:maintenance_tasks] = MaintenanceTasks.deprecator
27
- end
24
+ initializer "maintenance_tasks.deprecator" do
25
+ Rails.application.deprecators[:maintenance_tasks] = MaintenanceTasks.deprecator
28
26
  end
29
27
 
30
28
  config.to_prepare do
@@ -85,6 +85,30 @@ module MaintenanceTasks
85
85
  # @return [ActiveSupport::Duration] the threshold in seconds after which a task is considered stuck.
86
86
  mattr_accessor :stuck_task_duration, default: 5.minutes
87
87
 
88
+ # @!attribute status_reload_frequency
89
+ # @scope class
90
+ # The frequency at which to reload the run status during iteration.
91
+ # Defaults to 1 second, meaning reload status every second.
92
+ #
93
+ # @return [ActiveSupport::Duration, Numeric] the time interval between status reloads.
94
+ mattr_accessor :status_reload_frequency, default: 1.second
95
+
96
+ # @!attribute report_errors_as_handled
97
+ # @scope class
98
+ # How unexpected errors are reported to Rails.error.report.
99
+ #
100
+ # When an error occurs that isn't explicitly handled (e.g., via `report_on`),
101
+ # it gets reported to Rails.error.report. This setting determines whether
102
+ # these errors are marked as "handled" or "unhandled".
103
+ #
104
+ # The current default of `true` is for backwards compatibility, but it prevents
105
+ # error subscribers from distinguishing between expected and unexpected errors.
106
+ # Setting this to `false` provides more accurate error reporting and will become the default in v3.0.
107
+ #
108
+ # @see https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-report
109
+ # @return [Boolean] whether to report unexpected errors as handled (true) or unhandled (false).
110
+ mattr_accessor :report_errors_as_handled, default: true
111
+
88
112
  class << self
89
113
  DEPRECATION_MESSAGE = "MaintenanceTasks.error_handler is deprecated and will be removed in the 3.0 release. " \
90
114
  "Instead, reports will be sent to the Rails error reporter. Do not set a handler and subscribe " \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maintenance_tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.12.0
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Engineering
@@ -15,42 +15,42 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '7.0'
18
+ version: '7.1'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '7.0'
25
+ version: '7.1'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: activejob
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '7.0'
32
+ version: '7.1'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '7.0'
39
+ version: '7.1'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activerecord
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '7.0'
46
+ version: '7.1'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '7.0'
53
+ version: '7.1'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: csv
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -85,14 +85,14 @@ dependencies:
85
85
  requirements:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '7.0'
88
+ version: '7.1'
89
89
  type: :runtime
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
- version: '7.0'
95
+ version: '7.1'
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: zeitwerk
98
98
  requirement: !ruby/object:Gem::Requirement
@@ -182,7 +182,7 @@ homepage: https://github.com/Shopify/maintenance_tasks
182
182
  licenses:
183
183
  - MIT
184
184
  metadata:
185
- source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.12.0
185
+ source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.13.0
186
186
  allowed_push_host: https://rubygems.org
187
187
  rdoc_options: []
188
188
  require_paths:
@@ -191,14 +191,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
- version: '3.1'
194
+ version: '3.2'
195
195
  required_rubygems_version: !ruby/object:Gem::Requirement
196
196
  requirements:
197
197
  - - ">="
198
198
  - !ruby/object:Gem::Version
199
199
  version: '0'
200
200
  requirements: []
201
- rubygems_version: 3.6.8
201
+ rubygems_version: 3.7.2
202
202
  specification_version: 4
203
203
  summary: A Rails engine for queuing and managing maintenance tasks
204
204
  test_files: []