Module: Postburner::Execution
- Extended by:
- ActiveSupport::Concern
- Included in:
- Job
- Defined in:
- app/concerns/postburner/execution.rb
Overview
Concern providing job execution methods for Postburner jobs.
Handles the full job execution lifecycle including validation, callbacks, timing tracking, error handling, and state management. Provides both the class-level entry point for workers and the instance-level execution logic.
Instance Method Summary collapse
-
#perform!(args = {}) ⇒ void
Executes the job with full lifecycle management and error handling.
Instance Method Details
#perform!(args = {}) ⇒ void
Does not execute if queued_at is nil, in the future, already processed, or removed
Premature execution (before run_at) is delegated to queue strategy
This method returns an undefined value.
Executes the job with full lifecycle management and error handling.
This is the main execution method called by Postburner workers or test strategies. Performs validation checks, executes callbacks, calls the subclass #perform method, tracks timing and statistics, and handles errors.
Execution flow:
-
Runs attempt callbacks (fires on every retry)
-
Updates attempting metadata (attempting_at, attempts, lag)
-
Validates job state (queued, not processed, not removed, not premature)
-
Runs processing callbacks
-
Calls subclass #perform method
-
Runs processed callbacks (only on success)
-
Updates completion metadata (processed_at, duration)
-
Logs and tracks any exceptions
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'app/concerns/postburner/execution.rb', line 94 def perform!(args={}) run_callbacks :attempt do self.attempting self.update_columns( attempting_at: self.attempting_at, attempts: self.attempts, attempt_count: self.attempts.length, lag: self.lag, processing_at: Time.current, ) begin if self.queued_at.nil? self.log! "Not Queued", level: :error return end if self.queued_at > Time.current self.log! "Future Queued", level: :error return end if self.processed_at.present? self.log! "Already Processed", level: :error self.delete! return end if self.removed_at.present? self.log! "Removed", level: :error return end if self.run_at && self.run_at.to_i > Time.current.to_i Postburner.queue_strategy.handle_premature_perform(self) return end self.log!("START (bkid #{self.bkid})") run_callbacks :processing do begin method(:perform).arity == 0 ? self.perform : self.perform(args) rescue Exception => exception self. self.log! '[Postburner] Exception raised during perform prevented completion.' raise exception end end self.log!("DONE (bkid #{self.bkid})") begin now = Time.current _duration = (now - self.processing_at) * 1000 rescue nil run_callbacks :processed do ( processed_at: now, duration: _duration, ) end rescue Exception => e self.log_exception!(e) self.log! '[Postburner] Could not set data after processing.' # TODO README doesn't retry if Postburner is to blame end rescue Exception => exception self.log_exception!(exception) handle_retry_or_raise(exception) end end # run_callbacks :attempt end |