module Resque # A Resque::Job represents a unit of work. Each job lives on a # single queue and has an associated payload object. The payload # is a hash with two attributes: `class` and `args`. The `class` is # the name of the Ruby class which should be used to run the # job. The `args` are an array of arguments which should be passed # to the Ruby class's `perform` class-level method. # # You can manually run a job using this code: # # job = Resque::Job.reserve(:high) # klass = Resque::Job.constantize(job.payload['class']) # klass.perform(*job.payload['args']) class Job include Helpers extend Helpers # The worker object which is currently processing this job. attr_accessor :worker # The name of the queue from which this job was pulled (or is to be # placed) attr_reader :queue # This job's associated payload object. attr_reader :payload def initialize(queue, payload) @queue = queue @payload = payload end # Creates a job by placing it on a queue. Expects a string queue # name, a string class name, and an optional array of arguments to # pass to the class' `perform` method. # # Raises an exception if no queue or class is given. def self.create(queue, klass, *args) if queue.to_s.empty? raise NoQueueError.new("Jobs must be placed onto a queue.") end if klass.to_s.empty? raise NoClassError.new("Jobs must be given a class.") end Resque.push(queue, :class => klass.to_s, :args => args) end # Given a string queue name, returns an instance of Resque::Job # if any jobs are available. If not, returns nil. def self.reserve(queue) return unless payload = Resque.pop(queue) new(queue, payload) end # Attempts to perform the work represented by this job instance. # Calls #perform on the class given in the payload with the # arguments given in the payload. def perform args ? payload_class.perform(*args) : payload_class.perform end # Returns the actual class constant represented in this job's payload. def payload_class @payload_class ||= constantize(@payload['class']) end # Returns an array of args represented in this job's payload. def args @payload['args'] end # Given an exception object, hands off the needed parameters to # the Failure module. def fail(exception) Failure.create \ :payload => payload, :exception => exception, :worker => worker, :queue => queue end # Creates an identical job, essentially placing this job back on # the queue. def recreate self.class.create(queue, payload_class, *args) end # String representation def inspect obj = @payload "(Job{%s} | %s | %s)" % [ @queue, obj['class'], obj['args'].inspect ] end # Equality def ==(other) queue == other.queue && payload_class == other.payload_class && args == other.args end end end