maintenance_tasks 2.12.0 → 2.14.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: 7ceffb83ecb318ecf0edd66c78f55d4dd51c6528d4faf72d6e7ca66efa83db02
4
+ data.tar.gz: 360bc77f347ac909ed96a30495f965cc908cc5fc7956f1edfa8c3b2aba385607
5
5
  SHA512:
6
- metadata.gz: 87d37b437e518c0398023335fe88cb0c7829387142873eeb01aa713df04f397e7711491f0ace1a32baae20f4f1a613313c59e95696deef73d6ecfad24b6fb267
7
- data.tar.gz: b0c5fce124651391b77b8f2e5d91f8eb84c0415744fda8429b11a64b730a2e1ef02335c05685a98946fffdfd5042aa3b6f2a23a645a454613acd364af612b09d
6
+ metadata.gz: b46d6c5afcb297a2be58c9e218cad173b4abf65d50784574ac5fb4afdbaeaf83fc9add501e0817c85190b6b0e4299988b9a3ca87d28a83147e912e10f8d98cfd
7
+ data.tar.gz: 5b4ecaeff775b36f909dfe80d50df4834d642ba1fbf09d9668d11d47d011a2bb1a8302b612a07d8bec9f0b4d14ffba2d33f53f6e46b9999b6b74df4c41f9571b
data/README.md CHANGED
@@ -242,8 +242,8 @@ seconds to process. Consider skipping the count (defining a `count` that returns
242
242
  `nil`) or use an approximation, eg: count the number of new lines:
243
243
 
244
244
  ```ruby
245
- def count(task)
246
- task.csv_content.count("\n") - 1
245
+ def count
246
+ csv_content.count("\n") - 1
247
247
  end
248
248
  ```
249
249
 
@@ -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
@@ -11,11 +11,17 @@ module MaintenanceTasks
11
11
  policy.style_src_elem(
12
12
  BULMA_CDN,
13
13
  # <style> tag in app/views/layouts/maintenance_tasks/application.html.erb
14
- "'sha256-WHHDQLdkleXnAN5zs0GDXC5ls41CHUaVsJtVpaNx+EM='",
14
+ "'sha256-b9tTK1UaF0U8792/A1vIUkeZwjPgECIOeKJdhYED06A='",
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