lib/activejob-status/status.rb
# frozen_string_literal: true
module ActiveJob
module Status
class Status
delegate :[], :to_s, :to_json, :inspect, to: :read
delegate :queued?, :working?, :completed?, :failed?, to: :status_inquiry
def initialize(job, options = {})
options = ActiveJob::Status.options.merge(options)
@defaults = options.fetch(:includes, [])
@storage = ActiveJob::Status::Storage.new(options.without(:includes))
@job = job
end
def []=(key, value)
update({key => value}, force: true)
end
def read
@storage.read(@job)
end
alias_method :to_h, :read
def update(payload, options = {})
if @job.respond_to?(:progress)
@job.progress.instance_variable_set(:@progress, payload[:progress]) if payload.include?(:progress)
@job.progress.instance_variable_set(:@total, payload[:total]) if payload.include?(:total)
end
@storage.update(@job, payload, **options)
end
def delete
@storage.delete(@job)
end
def job_id
@storage.job_id(@job)
end
def status
read[:status]
end
def progress
read.then do |hash|
hash[:progress].to_f / hash[:total].to_f
end
end
def present?
read.present?
end
def status_inquiry
status.to_s.inquiry
end
# Update default data
def update_defaults(status_key)
raise "cannot call #update_defaults when status is accessed from outside the job" if @job.is_a?(String)
payload = {}
payload[:status] = status_key if @defaults.include?(:status)
payload[:serialized_job] = @job.serialize if @defaults.include?(:serialized_job)
update(payload, force: true)
end
def catch_exception(e)
raise "cannot call #catch_exception when status is accessed from outside the job" if @job.is_a?(String)
payload = {}
payload[:status] = :failed if @defaults.include?(:status)
payload[:serialized_job] = @job.serialize if @defaults.include?(:serialized_job)
if @defaults.include?(:exception)
message = e.message
message = e.original_message if e.respond_to?(:original_message)
payload[:exception] = {class: e.class.name, message: message}
end
update(payload, force: true)
end
end
end
end