maintenance_tasks 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2869ba1c05cb80edb54803f50037bb45b388a5489bec724a79617d2890e78fdc
4
- data.tar.gz: 5a936d433f102642e972f4c04e7fd96817193f0075b252e942c1ff86bb6a0e06
3
+ metadata.gz: b984293788834b153823e857dad5020b8cca1902037c97fd158401c1da3cfee3
4
+ data.tar.gz: 0c079b820fbfd3d7e26e7c19585ac8b41199de92f7a71e671a63c7db46b60d06
5
5
  SHA512:
6
- metadata.gz: 5e054a909fd05bacc7482caa7cba9cc69ed15850bdec1e0bbf09466426ad6bcfadd12c086a4efe185eb5be1edc40b3fbacaca34b555fac39fa0dcfac2df50405
7
- data.tar.gz: fa1c8baed4e9cc6b34acd03e9c16ef2266da288293da212fb96c03d6a6be2d87fb5599e167e4d629e80f16a80127b611ffe6b8895867958a92675dca06457e48
6
+ metadata.gz: f43e5c6535246bf7259bb21cfd1eb3f48f356a9f1f2e83fea19096cdff8610a601d4ea96b623d63bbecbaa593d1022a34fd16210896f83852f64c3e3bf003b41
7
+ data.tar.gz: a506d5e89ec233e60a59c428801d8e2e79a57f6604f8ab9cf97882b71bf69f4304f7d1fa53ac33ecd4ab5bb76f9de3774cbf9d1bfdd7cdff52af1849379b7e6d
data/README.md CHANGED
@@ -156,6 +156,32 @@ module Maintenance
156
156
  end
157
157
  ```
158
158
 
159
+ #### Customizing the Batch Size
160
+
161
+ When processing records from an Active Record Relation, records are fetched in
162
+ batches internally, and then each record is passed to the `#process` method.
163
+ Maintenance Tasks will query the database to fetch records in batches of 100 by
164
+ default, but the batch size can be modified using the `collection_batch_size` macro:
165
+
166
+ ```ruby
167
+ # app/tasks/maintenance/update_posts_task.rb
168
+
169
+ module Maintenance
170
+ class UpdatePostsTask < MaintenanceTasks::Task
171
+ # Fetch records in batches of 1000
172
+ collection_batch_size(1000)
173
+
174
+ def collection
175
+ Post.all
176
+ end
177
+
178
+ def process(post)
179
+ post.update!(content: "New content!")
180
+ end
181
+ end
182
+ end
183
+ ```
184
+
159
185
  ### Creating a CSV Task
160
186
 
161
187
  You can also write a Task that iterates on a CSV file. Note that writing CSV
@@ -497,7 +523,10 @@ end
497
523
 
498
524
  ### Subscribing to instrumentation events
499
525
 
500
- If you are interested in actioning a specific task event, please refer to the [Using Task Callbacks](#using-task-callbacks) section below. However, if you want to subscribe to all events, irrespective of the task, you can use the following Active Support notifications:
526
+ If you are interested in actioning a specific task event, please refer to the
527
+ [Using Task Callbacks](#using-task-callbacks) section below. However, if you
528
+ want to subscribe to all events, irrespective of the task, you can use the
529
+ following Active Support notifications:
501
530
 
502
531
  ```ruby
503
532
  enqueued.maintenance_tasks # This event is published when a task has been enqueued by the user.
@@ -507,7 +536,8 @@ paused.maintenance_tasks # This event is published when a task is paused by
507
536
  errored.maintenance_tasks # This event is published when the task's code produces an unhandled exception.
508
537
  ```
509
538
 
510
- These notifications offer a way to monitor the lifecycle of maintenance tasks in your application.
539
+ These notifications offer a way to monitor the lifecycle of maintenance tasks in
540
+ your application.
511
541
 
512
542
  Usage example:
513
543
 
@@ -723,9 +753,9 @@ end
723
753
  ### Writing tests for a Task that uses a custom enumerator
724
754
 
725
755
  Tests for tasks that use custom enumerators need to instantiate the task class
726
- in order to call `#build_enumerator`. Once the task instance is set up, validate
727
- that `#build_enumerator` returns an enumerator yielding pairs of [item, cursor]
728
- as expected.
756
+ in order to call `#enumerator_builder`. Once the task instance is set up,
757
+ validate that `#enumerator_builder` returns an enumerator yielding pairs of
758
+ `[item, cursor]` as expected.
729
759
 
730
760
  ```ruby
731
761
  # test/tasks/maintenance/custom_enumerating_task.rb
@@ -738,8 +768,8 @@ module Maintenance
738
768
  @task = CustomEnumeratingTask.new
739
769
  end
740
770
 
741
- test "#build_enumerator returns enumerator yielding pairs of [item, cursor]" do
742
- enum = @task.build_enumerator(cursor: 0)
771
+ test "#enumerator_builder returns enumerator yielding pairs of [item, cursor]" do
772
+ enum = @task.enumerator_builder(cursor: 0)
743
773
  expected_items = [:b, :c]
744
774
 
745
775
  assert_equal 2, enum.size
@@ -32,13 +32,16 @@ module MaintenanceTasks
32
32
 
33
33
  def build_enumerator(_run, cursor:)
34
34
  cursor ||= @run.cursor
35
+ self.cursor_position = cursor
35
36
  @collection_enum = @task.enumerator_builder(cursor: cursor)
36
37
 
37
38
  @collection_enum ||= case (collection = @task.collection)
38
39
  when :no_collection
39
40
  enumerator_builder.build_once_enumerator(cursor: nil)
40
41
  when ActiveRecord::Relation
41
- enumerator_builder.active_record_on_records(collection, cursor: cursor, columns: @task.cursor_columns)
42
+ options = { cursor: cursor, columns: @task.cursor_columns }
43
+ options[:batch_size] = @task.active_record_enumerator_batch_size if @task.active_record_enumerator_batch_size
44
+ enumerator_builder.active_record_on_records(collection, **options)
42
45
  when ActiveRecord::Batches::BatchEnumerator
43
46
  if collection.start || collection.finish
44
47
  raise ArgumentError, <<~MSG.squish
@@ -163,6 +166,7 @@ module MaintenanceTasks
163
166
  end
164
167
 
165
168
  def on_error(error)
169
+ task_context = {}
166
170
  @ticker.persist if defined?(@ticker)
167
171
 
168
172
  if defined?(@run)
@@ -174,8 +178,6 @@ module MaintenanceTasks
174
178
  started_at: @run.started_at,
175
179
  ended_at: @run.ended_at,
176
180
  }
177
- else
178
- task_context = {}
179
181
  end
180
182
  errored_element = @errored_element if defined?(@errored_element)
181
183
  ensure
@@ -18,6 +18,12 @@ module MaintenanceTasks
18
18
  # @api private
19
19
  class_attribute :throttle_conditions, default: []
20
20
 
21
+ # The number of active records to fetch in a single query when iterating
22
+ # over an Active Record collection task.
23
+ #
24
+ # @api private
25
+ class_attribute :active_record_enumerator_batch_size
26
+
21
27
  # @api private
22
28
  class_attribute :collection_builder_strategy, default: NullCollectionBuilder.new
23
29
 
@@ -79,6 +85,7 @@ module MaintenanceTasks
79
85
  end
80
86
 
81
87
  csv_options[:headers] = true unless csv_options.key?(:headers)
88
+ csv_options[:encoding] ||= Encoding.default_external
82
89
  self.collection_builder_strategy = if in_batches
83
90
  BatchCsvCollectionBuilder.new(in_batches, **csv_options)
84
91
  else
@@ -137,6 +144,14 @@ module MaintenanceTasks
137
144
  self.throttle_conditions += [{ throttle_on: condition, backoff: backoff_as_proc }]
138
145
  end
139
146
 
147
+ # Limit the number of records that will be fetched in a single query when
148
+ # iterating over an Active Record collection task.
149
+ #
150
+ # @param size [Integer] the number of records to fetch in a single query.
151
+ def collection_batch_size(size)
152
+ self.active_record_enumerator_batch_size = size
153
+ end
154
+
140
155
  # Initialize a callback to run after the task starts.
141
156
  #
142
157
  # @param filter_list apply filters to the callback
@@ -44,7 +44,7 @@
44
44
 
45
45
  <h4 class="title is-4">Active Runs</h4>
46
46
 
47
- <%= render @task.active_runs %>
47
+ <%= render partial: "maintenance_tasks/runs/run", collection: @task.active_runs %>
48
48
  <% end %>
49
49
 
50
50
  <% if @runs_page.records.present? %>
@@ -52,7 +52,7 @@
52
52
 
53
53
  <h4 class="title is-4">Previous Runs</h4>
54
54
 
55
- <%= render @runs_page.records %>
55
+ <%= render partial: "maintenance_tasks/runs/run", collection: @runs_page.records %>
56
56
 
57
57
  <%= link_to "Next page", task_path(@task, cursor: @runs_page.next_cursor) unless @runs_page.last? %>
58
58
  <% end %>
@@ -10,7 +10,7 @@ module MaintenanceTasks
10
10
 
11
11
  # Mounts the engine in the host application's config/routes.rb
12
12
  def mount_engine
13
- route("mount MaintenanceTasks::Engine => \"/maintenance_tasks\"")
13
+ route("mount MaintenanceTasks::Engine, at: \"/maintenance_tasks\"")
14
14
  end
15
15
 
16
16
  # Copies engine migrations to host application and migrates the database
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.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Engineering
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-16 00:00:00.000000000 Z
11
+ date: 2024-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '6.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: csv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: job-iteration
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +108,7 @@ dependencies:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: 2.6.2
97
- description:
111
+ description:
98
112
  email: gems@shopify.com
99
113
  executables:
100
114
  - maintenance_tasks
@@ -171,9 +185,9 @@ homepage: https://github.com/Shopify/maintenance_tasks
171
185
  licenses:
172
186
  - MIT
173
187
  metadata:
174
- source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.7.0
188
+ source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.8.0
175
189
  allowed_push_host: https://rubygems.org
176
- post_install_message:
190
+ post_install_message:
177
191
  rdoc_options: []
178
192
  require_paths:
179
193
  - lib
@@ -188,8 +202,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
202
  - !ruby/object:Gem::Version
189
203
  version: '0'
190
204
  requirements: []
191
- rubygems_version: 3.5.9
192
- signing_key:
205
+ rubygems_version: 3.5.17
206
+ signing_key:
193
207
  specification_version: 4
194
208
  summary: A Rails engine for queuing and managing maintenance tasks
195
209
  test_files: []