Class: MaintenanceTasks::Task
- Inherits:
-
Object
- Object
- MaintenanceTasks::Task
- Extended by:
- ActiveSupport::DescendantsTracker
- Includes:
- ActiveModel::AttributeAssignment, ActiveModel::Attributes, ActiveModel::Validations, ActiveSupport::Callbacks, ActiveSupport::Rescuable
- Defined in:
- app/models/maintenance_tasks/task.rb
Overview
Base class that is inherited by the host application’s task classes.
Defined Under Namespace
Classes: NotFoundError
Instance Attribute Summary collapse
-
#metadata ⇒ Object
Returns the value of attribute metadata.
Class Method Summary collapse
-
.after_cancel(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task is cancelled.
-
.after_complete(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task completes.
-
.after_error(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task produces an error.
-
.after_interrupt(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task is interrupted.
-
.after_pause(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task pauses.
-
.after_start(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task starts.
-
.available_tasks ⇒ Array<Class>
Loads and returns a list of concrete classes that inherit from the Task superclass.
-
.collection ⇒ Object
Returns the collection for this Task.
-
.collection_batch_size(size) ⇒ Object
Limit the number of records that will be fetched in a single query when iterating over an Active Record collection task.
-
.count ⇒ Object
Returns the count of items for this Task.
-
.csv_collection(in_batches: nil, **csv_options) ⇒ Object
Make this Task a task that handles CSV.
-
.load_all ⇒ Array<Class>
Loads and returns a list of concrete classes that inherit from the Task superclass.
-
.mask_attribute(*attributes) ⇒ Object
Adds attribute names to sensitive arguments list.
-
.named(name) ⇒ Task
Finds a Task with the given name.
-
.no_collection ⇒ Object
Make this a Task that calls #process once, instead of iterating over a collection.
-
.process(*args) ⇒ Object
Processes one item.
-
.reload_status_every(frequency) ⇒ Object
Configure how frequently the run status should be reloaded during iteration.
-
.report_on(*exceptions, **report_options) ⇒ Object
Rescue listed exceptions during an iteration and report them to the error reporter, then continue iteration.
-
.throttle_on(backoff: 30.seconds, &condition) ⇒ Object
Add a condition under which this Task will be throttled.
Instance Method Summary collapse
-
#collection ⇒ Object
The collection to be processed, delegated to the strategy.
-
#count ⇒ Integer?
Total count of iterations to be performed, delegated to the strategy.
-
#csv_content ⇒ String
The contents of a CSV file to be processed by a Task.
-
#csv_content=(csv_content) ⇒ Object
Set the contents of a CSV file to be processed by a Task.
-
#cursor_columns ⇒ Object
The columns used to build the ‘ORDER BY` clause of the query for iteration.
-
#enumerator_builder(cursor:) ⇒ Enumerator
Default enumerator builder.
-
#has_csv_content? ⇒ Boolean
Returns whether the Task handles CSV.
-
#no_collection? ⇒ Boolean
Returns whether the Task is collection-less.
-
#process(_item) ⇒ Object
Placeholder method to raise in case a subclass fails to implement the expected instance method.
Instance Attribute Details
#metadata ⇒ Object
Returns the value of attribute metadata.
44 45 46 |
# File 'app/models/maintenance_tasks/task.rb', line 44 def @metadata end |
Class Method Details
.after_cancel(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task is cancelled.
221 222 223 |
# File 'app/models/maintenance_tasks/task.rb', line 221 def after_cancel(*filter_list, &block) set_callback(:cancel, :after, *filter_list, &block) end |
.after_complete(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task completes.
197 198 199 |
# File 'app/models/maintenance_tasks/task.rb', line 197 def after_complete(*filter_list, &block) set_callback(:complete, :after, *filter_list, &block) end |
.after_error(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task produces an error.
229 230 231 |
# File 'app/models/maintenance_tasks/task.rb', line 229 def after_error(*filter_list, &block) set_callback(:error, :after, *filter_list, &block) end |
.after_interrupt(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task is interrupted.
213 214 215 |
# File 'app/models/maintenance_tasks/task.rb', line 213 def after_interrupt(*filter_list, &block) set_callback(:interrupt, :after, *filter_list, &block) end |
.after_pause(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task pauses.
205 206 207 |
# File 'app/models/maintenance_tasks/task.rb', line 205 def after_pause(*filter_list, &block) set_callback(:pause, :after, *filter_list, &block) end |
.after_start(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task starts.
189 190 191 |
# File 'app/models/maintenance_tasks/task.rb', line 189 def after_start(*filter_list, &block) set_callback(:start, :after, *filter_list, &block) end |
.available_tasks ⇒ Array<Class>
Loads and returns a list of concrete classes that inherit from the Task superclass.
77 78 79 80 81 82 83 |
# File 'app/models/maintenance_tasks/task.rb', line 77 def available_tasks warn(<<~MSG.squish, category: :deprecated) MaintenanceTasks::Task.available_tasks is deprecated and will be removed from maintenance-tasks 3.0.0. Use .load_all instead. MSG load_all end |
.collection ⇒ Object
Returns the collection for this Task.
Especially useful for tests.
132 133 134 |
# File 'app/models/maintenance_tasks/task.rb', line 132 def collection new.collection end |
.collection_batch_size(size) ⇒ Object
Limit the number of records that will be fetched in a single query when iterating over an Active Record collection task.
165 166 167 |
# File 'app/models/maintenance_tasks/task.rb', line 165 def collection_batch_size(size) self.active_record_enumerator_batch_size = size end |
.count ⇒ Object
Returns the count of items for this Task.
Especially useful for tests.
141 142 143 |
# File 'app/models/maintenance_tasks/task.rb', line 141 def count new.count end |
.csv_collection(in_batches: nil, **csv_options) ⇒ Object
Make this Task a task that handles CSV.
An input to upload a CSV will be added in the form to start a Run. The collection and count method are implemented.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'app/models/maintenance_tasks/task.rb', line 95 def csv_collection(in_batches: nil, **) unless defined?(ActiveStorage) raise NotImplementedError, "Active Storage needs to be installed\n" \ "To resolve this issue run: bin/rails active_storage:install" end [:headers] = true unless .key?(:headers) [:encoding] ||= Encoding.default_external self.collection_builder_strategy = if in_batches BatchCsvCollectionBuilder.new(in_batches, **) else CsvCollectionBuilder.new(**) end end |
.load_all ⇒ Array<Class>
Loads and returns a list of concrete classes that inherit from the Task superclass.
68 69 70 71 |
# File 'app/models/maintenance_tasks/task.rb', line 68 def load_all load_constants descendants end |
.mask_attribute(*attributes) ⇒ Object
Adds attribute names to sensitive arguments list.
172 173 174 |
# File 'app/models/maintenance_tasks/task.rb', line 172 def mask_attribute(*attributes) self.masked_arguments += attributes end |
.named(name) ⇒ Task
Finds a Task with the given name.
54 55 56 57 58 59 60 61 62 |
# File 'app/models/maintenance_tasks/task.rb', line 54 def named(name) task = name.safe_constantize raise NotFoundError.new("Task #{name} not found.", name) unless task unless task.is_a?(Class) && task < Task raise NotFoundError.new("#{name} is not a Task.", name) end task end |
.no_collection ⇒ Object
Make this a Task that calls #process once, instead of iterating over a collection.
112 113 114 |
# File 'app/models/maintenance_tasks/task.rb', line 112 def no_collection self.collection_builder_strategy = MaintenanceTasks::NoCollectionBuilder.new end |
.process(*args) ⇒ Object
Processes one item.
Especially useful for tests.
123 124 125 |
# File 'app/models/maintenance_tasks/task.rb', line 123 def process(*args) new.process(*args) end |
.reload_status_every(frequency) ⇒ Object
Configure how frequently the run status should be reloaded during iteration. Use this to reduce database queries when processing large collections.
181 182 183 |
# File 'app/models/maintenance_tasks/task.rb', line 181 def reload_status_every(frequency) self.status_reload_frequency = frequency end |
.report_on(*exceptions, **report_options) ⇒ Object
Rescue listed exceptions during an iteration and report them to the error reporter, then continue iteration.
239 240 241 242 243 |
# File 'app/models/maintenance_tasks/task.rb', line 239 def report_on(*exceptions, **) rescue_from(*exceptions) do |exception| Rails.error.report(exception, source: "maintenance-tasks", **) end end |
.throttle_on(backoff: 30.seconds, &condition) ⇒ Object
Add a condition under which this Task will be throttled.
154 155 156 157 158 159 |
# File 'app/models/maintenance_tasks/task.rb', line 154 def throttle_on(backoff: 30.seconds, &condition) backoff_as_proc = backoff backoff_as_proc = -> { backoff } unless backoff.respond_to?(:call) self.throttle_conditions += [{ throttle_on: condition, backoff: backoff_as_proc }] end |
Instance Method Details
#collection ⇒ Object
The collection to be processed, delegated to the strategy.
290 291 292 |
# File 'app/models/maintenance_tasks/task.rb', line 290 def collection self.class.collection_builder_strategy.collection(self) end |
#count ⇒ Integer?
Total count of iterations to be performed, delegated to the strategy.
320 321 322 |
# File 'app/models/maintenance_tasks/task.rb', line 320 def count self.class.collection_builder_strategy.count(self) end |
#csv_content ⇒ String
The contents of a CSV file to be processed by a Task.
258 259 260 261 262 |
# File 'app/models/maintenance_tasks/task.rb', line 258 def csv_content raise NoMethodError unless has_csv_content? @csv_content end |
#csv_content=(csv_content) ⇒ Object
Set the contents of a CSV file to be processed by a Task.
267 268 269 270 271 |
# File 'app/models/maintenance_tasks/task.rb', line 267 def csv_content=(csv_content) raise NoMethodError unless has_csv_content? @csv_content = csv_content end |
#cursor_columns ⇒ Object
The columns used to build the ‘ORDER BY` clause of the query for iteration.
If cursor_columns returns nil, the query is ordered by the primary key. If cursor columns values change during an iteration, records may be skipped or yielded multiple times. More details in the documentation of JobIteration::EnumeratorBuilder.build_active_record_enumerator_on_records: www.rubydoc.info/gems/job-iteration/JobIteration/EnumeratorBuilder#build_active_record_enumerator_on_records-instance_method
302 303 304 |
# File 'app/models/maintenance_tasks/task.rb', line 302 def cursor_columns nil end |
#enumerator_builder(cursor:) ⇒ Enumerator
Default enumerator builder. You may override this method to return any Enumerator yielding pairs of ‘[item, item_cursor]`.
331 332 333 |
# File 'app/models/maintenance_tasks/task.rb', line 331 def enumerator_builder(cursor:) nil end |
#has_csv_content? ⇒ Boolean
Returns whether the Task handles CSV.
276 277 278 |
# File 'app/models/maintenance_tasks/task.rb', line 276 def has_csv_content? self.class.has_csv_content? end |
#no_collection? ⇒ Boolean
Returns whether the Task is collection-less.
283 284 285 |
# File 'app/models/maintenance_tasks/task.rb', line 283 def no_collection? self.class.no_collection? end |
#process(_item) ⇒ Object
Placeholder method to raise in case a subclass fails to implement the expected instance method.
313 314 315 |
# File 'app/models/maintenance_tasks/task.rb', line 313 def process(_item) raise NoMethodError, "#{self.class.name} must implement `process`." end |