class Resque::Plugins::State::Hash

Resque::Plugins::State::Hash is a Hash object that has helper methods for dealing with the common status attributes. It also has a number of class methods for creating/updating/retrieving status objects from Redis

Attributes

expire_in[R]

Public Class Methods

clear(range_start = nil, range_end = nil) click to toggle source

clear statuses from redis passing an optional range. See `statuses` for info about ranges

# File lib/resque/plugins/state/hash.rb, line 51
def self.clear(range_start = nil, range_end = nil)
  status_ids(range_start, range_end).each do |id|
    remove(id)
  end
end
clear_completed(range_start = nil, range_end = nil) click to toggle source
# File lib/resque/plugins/state/hash.rb, line 57
def self.clear_completed(range_start = nil, range_end = nil)
  status_ids(range_start, range_end).select do |id|
    if get(id).completed?
      remove(id)
      true
    else
      false
    end
  end
end
clear_failed(range_start = nil, range_end = nil) click to toggle source
# File lib/resque/plugins/state/hash.rb, line 68
def self.clear_failed(range_start = nil, range_end = nil)
  status_ids(range_start, range_end).select do |id|
    if get(id).failed?
      remove(id)
      true
    else
      false
    end
  end
end
count() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 79
def self.count
  redis.zcard(set_key)
end
create(uuid, *messages) click to toggle source

Create a status, a new UUID, passing the message to the status Returns the UUID of the new status.

# File lib/resque/plugins/state/hash.rb, line 12
def self.create(uuid, *messages)
  set(uuid, *messages)
  redis.zadd(set_key, Time.now.to_i, uuid)
  if @expire_in
    redis.zremrangebyscore(
      set_key, 0, Time.now.to_i - @expire_in
    )
  end
  uuid
end
expire_in=(seconds) click to toggle source

Set the expire_in time in seconds

# File lib/resque/plugins/state/hash.rb, line 238
def self.expire_in=(seconds)
  @expire_in = seconds.nil? ? nil : seconds.to_i
end
generate_uuid() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 262
def self.generate_uuid
  SecureRandom.hex.to_s
end
get(uuid) click to toggle source

Get a status by UUID. Returns a Resque::Plugins::State::Hash

# File lib/resque/plugins/state/hash.rb, line 24
def self.get(uuid)
  val = redis.get(status_key(uuid))
  val ? Resque::Plugins::State::Hash.new(uuid, decode(val)) : nil
end
hash_accessor(name, options = {}) click to toggle source
# File lib/resque/plugins/state/hash.rb, line 266
        def self.hash_accessor(name, options = {})
          options[:default] ||= nil
          coerce = options[:coerce] ? ".#{options[:coerce]}" : ''
          module_eval <<-EOT
          def #{name}
            value = (self['#{name}'] ? self['#{name}']#{coerce} : #{options[:default].inspect})
            yield value if block_given?
            value
          end

          def #{name}=(value)
            self['#{name}'] = value
          end

          def #{name}?
            !!self['#{name}']
          end
          EOT
        end
kill(uuid) click to toggle source

Kill the job at UUID on its next iteration this works by adding the UUID to a kill list (a.k.a. a list of jobs to be killed. Each iteration the job checks if it should be killed by calling tick or at. If so, it raises a Resque::Plugins::State::Killed error and sets the status to 'killed'.

# File lib/resque/plugins/state/hash.rb, line 120
def self.kill(uuid)
  redis.sadd(kill_key, uuid)
end
kill_ids() click to toggle source

Return the UUIDs of the jobs on the kill list

# File lib/resque/plugins/state/hash.rb, line 130
def self.kill_ids
  redis.smembers(kill_key)
end
kill_key() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 250
def self.kill_key
  '_kill'
end
killall(range_start = nil, range_end = nil) click to toggle source

Kills num jobs within range starting with the most recent first. By default kills all jobs. Note that the same conditions apply as kill, i.e. only jobs that check on each iteration by calling tick or at are eligible to killed. @param [Numeric] range_start The optional starting range @param [Numeric] range_end The optional ending range @example killing the last 20 submitted jobs

Resque::Plugins::State::Hash.killall(0, 20)
# File lib/resque/plugins/state/hash.rb, line 142
def self.killall(range_start = nil, range_end = nil)
  status_ids(range_start, range_end).collect do |id|
    kill(id)
  end
end
killed(uuid) click to toggle source

Remove the job at UUID from the kill list

# File lib/resque/plugins/state/hash.rb, line 125
def self.killed(uuid)
  redis.srem(kill_key, uuid)
end
lock(key, timeout = 3600) click to toggle source

Set a lock key to allow jobs to run as singletons. Optional timeout in seconds

# File lib/resque/plugins/state/hash.rb, line 216
def self.lock(key, timeout = 3600)
  redis.setnx("_lock-#{key}", key)
  redis.expire("_lock-#{key}", timeout)
end
locked?(key) click to toggle source

Check whether a key on the wait list

# File lib/resque/plugins/state/hash.rb, line 227
def self.locked?(key)
  redis.sismember("_lock-#{key}", key)
end
mget(uuids) click to toggle source

Get statuses by UUID. Returns array of Resque::Plugins::State::Hash

# File lib/resque/plugins/state/hash.rb, line 30
def self.mget(uuids)
  return [] if uuids.empty?
  status_keys = uuids.map { |u| status_key(u) }
  vals = redis.mget(*status_keys)

  uuids.zip(vals).map do |uuid, val|
    val ? Resque::Plugins::State::Hash.new(uuid, decode(val)) : nil
  end
end
new(*args) click to toggle source

Create a new Resque::Plugins::State::Hash object. If multiple arguments are passed it is assumed the first argument is the UUID and the rest are status objects. All arguments are subsequentily merged in order. Strings are assumed to be messages.

Calls superclass method
# File lib/resque/plugins/state/hash.rb, line 307
def initialize(*args)
  super nil
  base_status = {
    'time' => Time.now.to_i,
    'status' => Resque::Plugins::State::STATUS_QUEUED
  }
  base_status['uuid'] = args.shift if args.length > 1
  status_hash = args.inject(base_status) do |final, m|
    m = { 'message' => m } if m.is_a?(String)
    final.merge(m || {})
  end
  replace(status_hash)
end
no_revert(uuid) click to toggle source

Remove the job at UUID from the revert list; needed to handle jobs that don't support revert

# File lib/resque/plugins/state/hash.rb, line 200
def self.no_revert(uuid)
  redis.srem(revert_key, uuid)
end
pause(uuid) click to toggle source

pause the job at UUID on its next iteration this works by adding the UUID to a pause list (a.k.a. a list of jobs to be pauseed. Each iteration the job checks if it should be pauseed by calling tick or at. If so, it sleeps for 10 seconds before checking again if it should continue sleeping

# File lib/resque/plugins/state/hash.rb, line 157
def self.pause(uuid)
  redis.sadd(pause_key, uuid)
end
pause_ids() click to toggle source

Return the UUIDs of the jobs on the pause list

# File lib/resque/plugins/state/hash.rb, line 167
def self.pause_ids
  redis.smembers(pause_key)
end
pause_key() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 254
def self.pause_key
  '_pause'
end
pauseall(range_start = nil, range_end = nil) click to toggle source

pauses num jobs within range starting with the most recent first. By default pauses all jobs. Note that the same conditions apply as pause, i.e. only jobs that check on each iteration by calling tick or at are eligible to pauseed. @param [Numeric] range_start The optional starting range @param [Numeric] range_end The optional ending range @example pauseing the last 20 submitted jobs

Resque::Plugins::State::Hash.pauseall(0, 20)
# File lib/resque/plugins/state/hash.rb, line 179
def self.pauseall(range_start = nil, range_end = nil)
  status_ids(range_start, range_end).collect do |id|
    pause(id)
  end
end
remove(uuid) click to toggle source
# File lib/resque/plugins/state/hash.rb, line 83
def self.remove(uuid)
  redis.del(status_key(uuid))
  redis.zrem(set_key, uuid)
end
revert(uuid) click to toggle source

revert the job at UUID on its next iteration this works by adding the UUID to a revert list (a.k.a. a list of jobs to be reverted. Each iteration the job checks if it should be reverted by calling tick or at. If so, it sleeps for 10 seconds before checking again if it should continue sleeping

# File lib/resque/plugins/state/hash.rb, line 194
def self.revert(uuid)
  redis.sadd(revert_key, uuid)
end
revert_ids() click to toggle source

Return the UUIDs of the jobs on the revert list

# File lib/resque/plugins/state/hash.rb, line 205
def self.revert_ids
  redis.smembers(revert_key)
end
revert_key() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 258
def self.revert_key
  '_revert'
end
set(uuid, *messages) click to toggle source

set a status by UUID. messages can be any number of strings or hashes that are merged in order to create a single status.

# File lib/resque/plugins/state/hash.rb, line 42
def self.set(uuid, *messages)
  val = Resque::Plugins::State::Hash.new(uuid, *messages)
  redis.set(status_key(uuid), encode(val))
  redis.expire(status_key(uuid), expire_in) if expire_in
  val
end
set_key() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 246
def self.set_key
  '_statuses'
end
should_kill?(uuid) click to toggle source

Check whether a job with UUID is on the kill list

# File lib/resque/plugins/state/hash.rb, line 149
def self.should_kill?(uuid)
  redis.sismember(kill_key, uuid)
end
should_pause?(uuid) click to toggle source

Check whether a job with UUID is on the pause list

# File lib/resque/plugins/state/hash.rb, line 186
def self.should_pause?(uuid)
  redis.sismember(pause_key, uuid)
end
should_revert?(uuid) click to toggle source

Check whether a job with UUID is on the revert list

# File lib/resque/plugins/state/hash.rb, line 210
def self.should_revert?(uuid)
  redis.sismember(revert_key, uuid)
end
status_ids(range_start = nil, range_end = nil) click to toggle source

Return the num most recent status/job UUIDs in reverse chronological order.

# File lib/resque/plugins/state/hash.rb, line 102
def self.status_ids(range_start = nil, range_end = nil)
  if range_end && range_start
    # Because we want a reverse chronological order, we need to get a
    # range starting by the higest negative number. The ordering is
    # transparent from the API user's perspective so we need to convert
    # the passed params
    (redis.zrevrange(set_key, range_start.abs, (range_end || 1).abs) || [])
  else
    # Because we want a reverse chronological order, we need to get a
    # range starting by the higest negative number.
    redis.zrevrange(set_key, 0, -1) || []
  end
end
status_key(uuid) click to toggle source
# File lib/resque/plugins/state/hash.rb, line 242
def self.status_key(uuid)
  "status:#{uuid}"
end
statuses(range_start = nil, range_end = nil) click to toggle source

Return num Resque::Plugins::State::Hash objects in reverse chronological order. By default returns the entire set. @param [Numeric] range_start The optional starting range @param [Numeric] range_end The optional ending range @example retuning the last 20 statuses

Resque::Plugins::State::Hash.statuses(0, 20)
# File lib/resque/plugins/state/hash.rb, line 95
def self.statuses(range_start = nil, range_end = nil)
  ids = status_ids(range_start, range_end)
  mget(ids).compact || []
end
unlock(key) click to toggle source

Remove a key from the lock list

# File lib/resque/plugins/state/hash.rb, line 222
def self.unlock(key)
  redis.srem("_lock-#{key}", key)
end
unpause(uuid) click to toggle source

Remove the job at UUID from the pause list

# File lib/resque/plugins/state/hash.rb, line 162
def self.unpause(uuid)
  redis.srem(pause_key, uuid)
end

Public Instance Methods

inspect() click to toggle source
# File lib/resque/plugins/state/hash.rb, line 382
def inspect
  "#<Resque::Plugins::State::Hash #{super}>"
end
json() click to toggle source

Return a JSON representation of the current object.

# File lib/resque/plugins/state/hash.rb, line 376
def json
  h = dup
  h['pct_complete'] = pct_complete
  self.class.encode(h)
end
killable?() click to toggle source

Can the job be killed? failed, completed, reverted, and killed jobs can't be killed, for obvious reasons

# File lib/resque/plugins/state/hash.rb, line 353
def killable?
  !failed? && !completed? && !killed? && !reverted?
end
pausable?() click to toggle source

Can the job be paused? failed, completed, paused, reverted, and killed jobs can't be paused, for obvious reasons

# File lib/resque/plugins/state/hash.rb, line 359
def pausable?
  !failed? && !completed? && !killed? && !paused? && !reverted?
end
pct_complete() click to toggle source

calculate the % completion of the job based on status, num and total

# File lib/resque/plugins/state/hash.rb, line 323
def pct_complete
  if completed?
    100
  elsif queued?
    0
  elsif failed?
    0
  else
    t = if total.nil?
          1
        else total
        end
    (((num || 0).to_f / t.to_f) * 100).to_i
  end
end
time() click to toggle source

Return the time of the status initialization. If set returns a Time object, otherwise returns nil

# File lib/resque/plugins/state/hash.rb, line 341
def time
  time? ? Time.at(self['time']) : nil
end
to_json(*_args) click to toggle source
# File lib/resque/plugins/state/hash.rb, line 370
def to_json(*_args)
  json
end