Class: MaintenanceTasks::Task
- Inherits:
-
Object
- Object
- MaintenanceTasks::Task
- Extended by:
- ActiveSupport::DescendantsTracker
- Includes:
- ActiveModel::AttributeAssignment, ActiveModel::Attributes, ActiveModel::Validations, ActiveSupport::Callbacks
- 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
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.
-
.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.
-
.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.
Class Method Details
.after_cancel(*filter_list, &block) ⇒ Object
Initialize a callback to run after the task is cancelled.
191 192 193 |
# File 'app/models/maintenance_tasks/task.rb', line 191 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.
167 168 169 |
# File 'app/models/maintenance_tasks/task.rb', line 167 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.
199 200 201 |
# File 'app/models/maintenance_tasks/task.rb', line 199 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.
183 184 185 |
# File 'app/models/maintenance_tasks/task.rb', line 183 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.
175 176 177 |
# File 'app/models/maintenance_tasks/task.rb', line 175 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.
159 160 161 |
# File 'app/models/maintenance_tasks/task.rb', line 159 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.
63 64 65 66 67 68 69 |
# File 'app/models/maintenance_tasks/task.rb', line 63 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.
118 119 120 |
# File 'app/models/maintenance_tasks/task.rb', line 118 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.
151 152 153 |
# File 'app/models/maintenance_tasks/task.rb', line 151 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.
127 128 129 |
# File 'app/models/maintenance_tasks/task.rb', line 127 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.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'app/models/maintenance_tasks/task.rb', line 81 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.
54 55 56 57 |
# File 'app/models/maintenance_tasks/task.rb', line 54 def load_all load_constants descendants end |
.named(name) ⇒ Task
Finds a Task with the given name.
40 41 42 43 44 45 46 47 48 |
# File 'app/models/maintenance_tasks/task.rb', line 40 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.
98 99 100 |
# File 'app/models/maintenance_tasks/task.rb', line 98 def no_collection self.collection_builder_strategy = MaintenanceTasks::NoCollectionBuilder.new end |
.process(*args) ⇒ Object
Processes one item.
Especially useful for tests.
109 110 111 |
# File 'app/models/maintenance_tasks/task.rb', line 109 def process(*args) new.process(*args) end |
.throttle_on(backoff: 30.seconds, &condition) ⇒ Object
Add a condition under which this Task will be throttled.
140 141 142 143 144 145 |
# File 'app/models/maintenance_tasks/task.rb', line 140 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.
248 249 250 |
# File 'app/models/maintenance_tasks/task.rb', line 248 def collection self.class.collection_builder_strategy.collection(self) end |
#count ⇒ Integer?
Total count of iterations to be performed, delegated to the strategy.
278 279 280 |
# File 'app/models/maintenance_tasks/task.rb', line 278 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.
216 217 218 219 220 |
# File 'app/models/maintenance_tasks/task.rb', line 216 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.
225 226 227 228 229 |
# File 'app/models/maintenance_tasks/task.rb', line 225 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
260 261 262 |
# File 'app/models/maintenance_tasks/task.rb', line 260 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]`.
289 290 291 |
# File 'app/models/maintenance_tasks/task.rb', line 289 def enumerator_builder(cursor:) nil end |
#has_csv_content? ⇒ Boolean
Returns whether the Task handles CSV.
234 235 236 |
# File 'app/models/maintenance_tasks/task.rb', line 234 def has_csv_content? self.class.has_csv_content? end |
#no_collection? ⇒ Boolean
Returns whether the Task is collection-less.
241 242 243 |
# File 'app/models/maintenance_tasks/task.rb', line 241 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.
271 272 273 |
# File 'app/models/maintenance_tasks/task.rb', line 271 def process(_item) raise NoMethodError, "#{self.class.name} must implement `process`." end |