Module: Delayed::Backend::Base
- Included in:
- ActiveRecord::Job, ActiveRecord::Job::Failed
- Defined in:
- lib/delayed/backend/base.rb
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- ON_HOLD_BLOCKER =
"blocker job"- ON_HOLD_LOCKED_BY =
"on hold"- ON_HOLD_COUNT =
50
Class Method Summary collapse
Instance Method Summary collapse
- #batch? ⇒ Boolean
- #expired? ⇒ Boolean
- #failed? ⇒ Boolean (also: #failed)
- #full_name ⇒ Object
- #hold! ⇒ Object
- #inferred_max_attempts ⇒ Object
- #initialize_defaults ⇒ Object
-
#invoke_job ⇒ Object
Moved into its own method so that new_relic can trace it.
- #locked? ⇒ Boolean
- #name ⇒ Object
- #on_hold? ⇒ Boolean
- #payload_object ⇒ Object
- #payload_object=(object) ⇒ Object
- #permanent_failure(error) ⇒ Object
-
#reschedule(error = nil, time = nil) ⇒ Object
Reschedule the job in the future (when a job fails).
- #reschedule_at ⇒ Object
- #unhold! ⇒ Object
-
#unlock ⇒ Object
Unlock this job (note: not saved to DB).
Class Method Details
.included(base) ⇒ Object
19 20 21 22 23 |
# File 'lib/delayed/backend/base.rb', line 19 def self.included(base) base.extend ClassMethods base.default_priority = Delayed::NORMAL_PRIORITY base.before_save :initialize_defaults end |
Instance Method Details
#batch? ⇒ Boolean
333 334 335 |
# File 'lib/delayed/backend/base.rb', line 333 def batch? payload_object.is_a?(Delayed::Batch::PerformableBatch) end |
#expired? ⇒ Boolean
233 234 235 |
# File 'lib/delayed/backend/base.rb', line 233 def expired? expires_at && (self.class.db_time_now >= expires_at) end |
#failed? ⇒ Boolean Also known as: failed
228 229 230 |
# File 'lib/delayed/backend/base.rb', line 228 def failed? failed_at end |
#full_name ⇒ Object
298 299 300 301 302 303 304 305 |
# File 'lib/delayed/backend/base.rb', line 298 def full_name obj = payload_object rescue nil if obj.respond_to?(:full_name) obj.full_name else name end end |
#hold! ⇒ Object
361 362 363 364 365 366 |
# File 'lib/delayed/backend/base.rb', line 361 def hold! self.locked_by = ON_HOLD_LOCKED_BY self.locked_at = self.class.db_time_now self.attempts = ON_HOLD_COUNT save! end |
#inferred_max_attempts ⇒ Object
237 238 239 |
# File 'lib/delayed/backend/base.rb', line 237 def inferred_max_attempts max_attempts || Delayed::Settings.max_attempts end |
#initialize_defaults ⇒ Object
424 425 426 427 |
# File 'lib/delayed/backend/base.rb', line 424 def initialize_defaults self.queue ||= Delayed::Settings.queue self.run_at ||= self.class.db_time_now end |
#invoke_job ⇒ Object
Moved into its own method so that new_relic can trace it.
320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/delayed/backend/base.rb', line 320 def invoke_job ActiveSupport::ExecutionContext[:job] = self Delayed::Worker.lifecycle.run_callbacks(:invoke_job, self) do Delayed::Job.in_delayed_job = true begin payload_object.perform ensure Delayed::Job.in_delayed_job = false ::ActiveRecord::Base.connection_handler.clear_active_connections!(nil) unless Rails.env.test? end end end |
#locked? ⇒ Boolean
343 344 345 |
# File 'lib/delayed/backend/base.rb', line 343 def locked? !!(locked_at || locked_by) end |
#name ⇒ Object
287 288 289 290 291 292 293 294 295 296 |
# File 'lib/delayed/backend/base.rb', line 287 def name @name ||= begin payload = payload_object if payload.respond_to?(:display_name) payload.display_name else payload.class.name end end end |
#on_hold? ⇒ Boolean
377 378 379 |
# File 'lib/delayed/backend/base.rb', line 377 def on_hold? locked_by == "on hold" && locked_at && self.attempts == ON_HOLD_COUNT end |
#payload_object ⇒ Object
283 284 285 |
# File 'lib/delayed/backend/base.rb', line 283 def payload_object @payload_object ||= deserialize(self["handler"]) end |
#payload_object=(object) ⇒ Object
307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/delayed/backend/base.rb', line 307 def payload_object=(object) @payload_object = object self["handler"] = object.to_yaml self["tag"] = if object.respond_to?(:tag) object.tag elsif object.is_a?(Module) "#{object}.perform" else "#{object.class}#perform" end end |
#permanent_failure(error) ⇒ Object
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/delayed/backend/base.rb', line 264 def permanent_failure(error) begin # notify the payload_object of a permanent failure invoke_payload_object_cb(:on_permanent_failure, error) rescue # don't allow a failed deserialization to prevent destroying the job end # optionally destroy the object destroy_self = true destroy_self = Delayed::Worker.on_max_failures.call(self, error) if Delayed::Worker.on_max_failures if destroy_self destroy else fail! end end |
#reschedule(error = nil, time = nil) ⇒ Object
Reschedule the job in the future (when a job fails). Uses an exponential scale depending on the number of failed attempts.
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/delayed/backend/base.rb', line 243 def reschedule(error = nil, time = nil) begin return_code = invoke_payload_object_cb(:on_failure, error) rescue # don't allow a failed deserialization to prevent rescheduling end self.attempts += 1 unless return_code == :unlock if self.attempts >= inferred_max_attempts permanent_failure error || "max attempts reached" elsif expired? permanent_failure error || "job has expired" else time ||= reschedule_at self.run_at = time unlock save! end end |
#reschedule_at ⇒ Object
347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/delayed/backend/base.rb', line 347 def reschedule_at new_time = self.class.db_time_now + (attempts**4) + 5 begin if payload_object.respond_to?(:reschedule_at) new_time = payload_object.reschedule_at( self.class.db_time_now, attempts ) end rescue # TODO: just swallow errors from reschedule_at ? end new_time end |
#unhold! ⇒ Object
368 369 370 371 372 373 374 375 |
# File 'lib/delayed/backend/base.rb', line 368 def unhold! self.locked_by = nil self.locked_at = nil self.attempts = 0 self.run_at = [self.class.db_time_now, run_at].max self.failed_at = nil save! end |
#unlock ⇒ Object
Unlock this job (note: not saved to DB)
338 339 340 341 |
# File 'lib/delayed/backend/base.rb', line 338 def unlock self.locked_at = nil self.locked_by = nil end |