class Cuetip::Models::Job

Constants

STATUSES

Public Instance Methods

execute(&block) click to toggle source

Execute the job

@return [Boolean] whether the job executed successfully or not

# File lib/cuetip/models/job.rb, line 71
def execute(&block)
  log "Beginning execution of job #{id} with #{class_name}"
  # Initialize a new instance of the job we wish to execute
  job_klass = class_name.constantize.new(self)

  # If the job has expired, we should not be executing this so we'll just
  # remove it from the queue and mark it as expired.
  if expired?
    log 'Job has expired'
    self.status = 'Expired'
    remove_from_queue
    Cuetip.config.emit(:expired, self, job_klass)
    return false
  end

  Cuetip.config.emit(:before_perform, self, job_klass)

  # If we have a block, call this so we can manipulate our actual job class
  # before execution if needed (mostly for testing)
  block.call(job_klass) if block_given?

  # Mark the job as runnign
  update!(status: 'Running', started_at: Time.now, executions: executions + 1)

  begin
    # Perform the job within a timeout
    Timeout.timeout(maximum_execution_time || 1.year) do
      job_klass.perform
    end
    # Mark the job as complete and remove it from the queue
    self.status = 'Complete'
    log 'Job completed successfully'
    remove_from_queue

    Cuetip.config.emit(:completed, self, job_klass)

    true
  rescue Exception, Timeout::TimeoutError => e
    log "Job failed with #{e.class} (#{e.message})"

    # If there's an error, mark the job as failed and copy exception
    # data into the job
    self.status = 'Failed'
    self.exception_class = e.class.name
    self.exception_message = e.message
    self.exception_backtrace = e.backtrace.join("\n")

    # Handle requeing the job if needed.
    if requeue_on_failure?
      # Requeue this job for execution again after the retry interval.
      new_job = queued_job.requeue(run_after: Time.now + retry_interval.to_i)
      log "Requeing job to run after #{new_job.run_after.to_s(:long)}"
      self.status = 'Pending'
    else
      # We're done with this job. We can't do any more retries.
      remove_from_queue
    end

    Cuetip.config.emit(:exception, e, self, job_klass)

    false
  end
ensure
  unless destroyed?
    self.finished_at = Time.now
    save!
  end
  Cuetip.config.emit(:finished, self, job_klass)
  log 'Finished processing'
end
expired?() click to toggle source

Has this job expired?

# File lib/cuetip/models/job.rb, line 34
def expired?
  ttl? ? expires_at <= Time.now : false
end
expires_at() click to toggle source

The time that this job expired

# File lib/cuetip/models/job.rb, line 39
def expires_at
  ttl? ? created_at + ttl : nil
end
log(text) click to toggle source

Log some text about this job

@param text [String]

# File lib/cuetip/models/job.rb, line 64
def log(text)
  Cuetip.logger.info "[#{id}] #{text}"
end
queued?() click to toggle source

Is this job in the queue

# File lib/cuetip/models/job.rb, line 29
def queued?
  queued_job.present?
end
remove_from_queue() click to toggle source

Remove this job from the queue

# File lib/cuetip/models/job.rb, line 49
def remove_from_queue
  queued_job&.destroy
  self.queued_job = nil
  log 'Removed from queue'

  if delete_after_execution?
    destroy
    log 'Removed job from database'
  end

end
requeue_on_failure?() click to toggle source

Should this job be requeued on a failure right now?

# File lib/cuetip/models/job.rb, line 44
def requeue_on_failure?
  retry_count && retry_interval ? executions <= retry_count : false
end