maintenance_tasks 2.3.2 → 2.3.3
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f292dbc04fbbb71588c0be3af0bc95bfb5de5ca27f9aa7562b681cad39c6241
|
4
|
+
data.tar.gz: d631953126ffbd114721fea778fc8d43f5c86c20461c04943c3127a1b6f9e0d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 146510c2a63f74b6084b43f9fa939c017e242b79ae0c453008b17b8e5c5e2332bd0d972ab4d8dce4d9d365836bcada8df8a7f1a7d717dc1d733232edd0830a4e
|
7
|
+
data.tar.gz: d1df2c04b6274843b32e4feb44a4bfb1eec3e64717ae67d78bbb440c08c34f24f63882d880dfc602529b2971f9bbfc9ce74345b848ecd3f780d1ab9270a610ec
|
data/README.md
CHANGED
@@ -1,9 +1,63 @@
|
|
1
|
-
#
|
1
|
+
# Maintenance Tasks
|
2
2
|
|
3
3
|
A Rails engine for queuing and managing maintenance tasks.
|
4
4
|
|
5
|
+
By ”maintenance task”, this project means a data migration, i.e. code that
|
6
|
+
changes data in the database, often to support schema migrations. For example,
|
7
|
+
in order to introduce a new `NOT NULL` column, it has to be added as nullable
|
8
|
+
first, backfilled with values, before finally being changed to `NOT NULL`.
|
9
|
+
This engine helps with the second part of this process, backfilling.
|
10
|
+
|
11
|
+
Maintenance tasks are collection-based tasks, usually using Active Record,
|
12
|
+
that update the data in your database. They can be paused or interrupted.
|
13
|
+
Maintenance tasks can operate [in batches](#processing-batch-collections) and
|
14
|
+
use [throttling](#throttling) to control the load on your database.
|
15
|
+
|
16
|
+
Maintenance tasks aren't meant to happen on a regular basis. They're used as
|
17
|
+
needed, or as one-offs. Normally maintenance tasks are ephemeral, so they are
|
18
|
+
used briefly and then deleted.
|
19
|
+
|
20
|
+
The Rails engine has a web-based UI for listing maintenance tasks, seeing
|
21
|
+
their status, and starting, pausing and restarting them.
|
22
|
+
|
5
23
|
[](https://www.youtube.com/watch?v=BTuvTQxlFzs)
|
6
24
|
|
25
|
+
## Should I Use Maintenance Tasks?
|
26
|
+
|
27
|
+
Maintenance tasks have a limited, specific job UI. While the engine can be
|
28
|
+
used to provide a user interface for other data changes, such as data changes
|
29
|
+
for support requests, we recommend you use regular application code for those
|
30
|
+
use cases instead. These inevitably require more flexibility than this engine
|
31
|
+
will be able to provide.
|
32
|
+
|
33
|
+
If your task shouldn't run as an Active Job, it probably isn't a good match
|
34
|
+
for this gem. If your task doesn't need to run in the background,
|
35
|
+
consider a runner script instead. If your task doesn't need to be
|
36
|
+
interruptible, consider a normal Active Job.
|
37
|
+
|
38
|
+
Maintenance tasks can be interrupted between iterations. If your task [isn't
|
39
|
+
collection-based](#tasks-that-dont-need-a-collection) (no CSV file or database
|
40
|
+
table) or has very large batches, it will get limited benefit from throttling
|
41
|
+
(pausing between iterations) or interrupting. This might be fine, or the added
|
42
|
+
complexity of maintenance Tasks over normal Active Jobs may not be worthwhile.
|
43
|
+
|
44
|
+
If your task updates your database schema instead of data, use a migration
|
45
|
+
instead of a maintenance task.
|
46
|
+
|
47
|
+
If your task happens regularly, consider Active Jobs with a scheduler or cron,
|
48
|
+
[job-iteration jobs](https://github.com/shopify/job-iteration) and/or [custom
|
49
|
+
rails_admin UIs][rails-admin-engines] instead of the Maintenance Tasks gem.
|
50
|
+
Maintenance tasks should be ephemeral, to suit their intentionally limited UI.
|
51
|
+
|
52
|
+
To create seed data for a new application, use the provided Rails
|
53
|
+
`db/seeds.rb` file instead.
|
54
|
+
|
55
|
+
If your application can't handle a half-completed migration, maintenance tasks
|
56
|
+
are probably the wrong tool. Remember that maintenance tasks are intentionally
|
57
|
+
pausable and can be cancelled halfway.
|
58
|
+
|
59
|
+
[rails-admin-engines]: https://www.ruby-toolbox.com/categories/rails_admin_interfaces
|
60
|
+
|
7
61
|
## Installation
|
8
62
|
|
9
63
|
To install the gem and run the install generator, execute:
|
@@ -168,6 +222,9 @@ Note that `#count` is calculated automatically based on the number of batches in
|
|
168
222
|
your collection, and your Task’s progress will be displayed in terms of batches
|
169
223
|
(not the total number of rows in your CSV).
|
170
224
|
|
225
|
+
Non-batched CSV tasks will have an effective batch size of 1, which can reduce
|
226
|
+
the efficiency of your database operations.
|
227
|
+
|
171
228
|
### Processing Batch Collections
|
172
229
|
|
173
230
|
The Maintenance Tasks gem supports processing Active Records in batches. This
|
@@ -213,7 +270,7 @@ inside `#process`.
|
|
213
270
|
### Tasks that don’t need a Collection
|
214
271
|
|
215
272
|
Sometimes, you might want to run a Task that performs a single operation, such
|
216
|
-
as enqueuing another background job or
|
273
|
+
as enqueuing another background job or querying an external API. The gem supports
|
217
274
|
collection-less tasks.
|
218
275
|
|
219
276
|
Generate a collection-less Task by running:
|
@@ -242,10 +299,12 @@ end
|
|
242
299
|
|
243
300
|
### Throttling
|
244
301
|
|
245
|
-
Maintenance
|
302
|
+
Maintenance tasks often modify a lot of data and can be taxing on your database.
|
246
303
|
The gem provides a throttling mechanism that can be used to throttle a Task when
|
247
|
-
a given condition is met. If a Task is throttled
|
248
|
-
retried after a backoff period has passed. The
|
304
|
+
a given condition is met. If a Task is throttled (the throttle block returns
|
305
|
+
true), it will be interrupted and retried after a backoff period has passed. The
|
306
|
+
default backoff is 30 seconds.
|
307
|
+
|
249
308
|
Specify the throttle condition as a block:
|
250
309
|
|
251
310
|
```ruby
|
@@ -277,7 +336,7 @@ Tasks can define multiple throttle conditions. Throttle conditions are inherited
|
|
277
336
|
by descendants, and new conditions will be appended without impacting existing
|
278
337
|
conditions.
|
279
338
|
|
280
|
-
The backoff can also be specified as a Proc:
|
339
|
+
The backoff can also be specified as a Proc that receives no arguments:
|
281
340
|
|
282
341
|
```ruby
|
283
342
|
# app/tasks/maintenance/update_posts_throttled_task.rb
|
@@ -362,7 +421,7 @@ module Maintenance
|
|
362
421
|
after_error :dangerous_notify
|
363
422
|
|
364
423
|
def dangerous_notify
|
365
|
-
# This error is rescued in favour of the original error causing the error flow.
|
424
|
+
# This error is rescued and ignored in favour of the original error causing the error flow.
|
366
425
|
raise NotDeliveredError
|
367
426
|
end
|
368
427
|
|
@@ -392,21 +451,21 @@ end
|
|
392
451
|
|
393
452
|
### Considerations when writing Tasks
|
394
453
|
|
395
|
-
|
454
|
+
Maintenance Tasks relies on the queue adapter configured for your application to
|
396
455
|
run the job which is processing your Task. The guidelines for writing Task may
|
397
456
|
depend on the queue adapter but in general, you should follow these rules:
|
398
457
|
|
399
458
|
* Duration of `Task#process`: processing a single element of the collection
|
400
459
|
should take less than 25 seconds, or the duration set as a timeout for Sidekiq
|
401
|
-
or the queue adapter configured in your application.
|
402
|
-
safely interrupted and resumed.
|
460
|
+
or the queue adapter configured in your application. Short batches allow the
|
461
|
+
Task to be safely interrupted and resumed.
|
403
462
|
* Idempotency of `Task#process`: it should be safe to run `process` multiple
|
404
463
|
times for the same element of the collection. Read more in [this Sidekiq best
|
405
464
|
practice][sidekiq-idempotent]. It’s important if the Task errors and you run
|
406
|
-
it again, because the same element that
|
407
|
-
again. It especially matters in the situation described
|
408
|
-
iteration duration exceeds the timeout: if the job is
|
409
|
-
elements may be processed again.
|
465
|
+
it again, because the same element that caused the Task to give an error may
|
466
|
+
well be processed again. It especially matters in the situation described
|
467
|
+
above, when the iteration duration exceeds the timeout: if the job is
|
468
|
+
re-enqueued, multiple elements may be processed again.
|
410
469
|
|
411
470
|
[sidekiq-idempotent]: https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional
|
412
471
|
|
@@ -636,8 +695,8 @@ re-enqueue the jobs that were in progress, the Task may be in a seemingly stuck
|
|
636
695
|
situation where it appears to be running but is not. In that situation, pausing
|
637
696
|
or cancelling it will not result in the Task being paused or cancelled, as the
|
638
697
|
Task will get stuck in a state of `pausing` or `cancelling`. As a work-around,
|
639
|
-
if a Task is `cancelling` for more than 5 minutes, you
|
640
|
-
|
698
|
+
if a Task is `cancelling` for more than 5 minutes, you can cancel it again.
|
699
|
+
It will then be marked as fully cancelled, allowing you to run it again.
|
641
700
|
|
642
701
|
### Configuring the gem
|
643
702
|
|
@@ -840,8 +899,8 @@ or email of the user who performed the maintenance task.
|
|
840
899
|
|
841
900
|
```ruby
|
842
901
|
# config/initializers/maintenance_tasks.rb
|
843
|
-
MaintenanceTasks.metadata = ->(
|
844
|
-
|
902
|
+
MaintenanceTasks.metadata = ->() do
|
903
|
+
{ user_email: current_user.email }
|
845
904
|
end
|
846
905
|
```
|
847
906
|
|
@@ -13,7 +13,7 @@ module MaintenanceTasks
|
|
13
13
|
task = Runner.run(
|
14
14
|
name: params.fetch(:task_id),
|
15
15
|
csv_file: params[:csv_file],
|
16
|
-
arguments: params.fetch(:
|
16
|
+
arguments: params.fetch(:task, {}).permit!.to_h,
|
17
17
|
metadata: instance_exec(&MaintenanceTasks.metadata || -> {}),
|
18
18
|
&block
|
19
19
|
)
|
@@ -15,7 +15,7 @@
|
|
15
15
|
<% parameter_names = @task.parameter_names %>
|
16
16
|
<% if parameter_names.any? %>
|
17
17
|
<div class="block">
|
18
|
-
<%=
|
18
|
+
<%= fields_for :task, @task.new do |ff| %>
|
19
19
|
<% parameter_names.each do |parameter_name| %>
|
20
20
|
<div class="field">
|
21
21
|
<%= ff.label parameter_name, parameter_name, class: "label is-family-monospace" %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maintenance_tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -156,7 +156,7 @@ homepage: https://github.com/Shopify/maintenance_tasks
|
|
156
156
|
licenses:
|
157
157
|
- MIT
|
158
158
|
metadata:
|
159
|
-
source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.3.
|
159
|
+
source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.3.3
|
160
160
|
allowed_push_host: https://rubygems.org
|
161
161
|
post_install_message:
|
162
162
|
rdoc_options: []
|
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
173
|
- !ruby/object:Gem::Version
|
174
174
|
version: '0'
|
175
175
|
requirements: []
|
176
|
-
rubygems_version: 3.4.
|
176
|
+
rubygems_version: 3.4.20
|
177
177
|
signing_key:
|
178
178
|
specification_version: 4
|
179
179
|
summary: A Rails engine for queuing and managing maintenance tasks
|