Module: Resque::Plugins::BetterUnique::ClassMethods

Defined in:
lib/resque/plugins/better_unique.rb

Instance Method Summary collapse

Instance Method Details

#around_perform_unique_lock(*args) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/resque/plugins/better_unique.rb', line 67

def around_perform_unique_lock(*args)
  case unique_job_mode
  when :until_executing
    release_lock(*args)
  when :while_executing
    return if locked?(*args) || !set_lock(*args)
  end
  yield
ensure
  if [:until_executed, :while_executing].include?(unique_job_mode)
    release_lock(*args)
  end
end

#before_enqueue_unique_lock(*args) ⇒ Object

:nocov:



59
60
61
62
63
64
65
# File 'lib/resque/plugins/better_unique.rb', line 59

def before_enqueue_unique_lock(*args)
  if [:until_executing, :until_executed, :until_timeout].include?(unique_job_mode)
    return false if locked?(*args)
    set_lock(*args)
  end
  true
end

#lock_key(*args) ⇒ Object

Override in your job to control the lock key. It is passed the same arguments as ‘perform`, that is, your job’s payload.



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/resque/plugins/better_unique.rb', line 14

def lock_key(*args)
  unique_args = unique_job_options[:unique_args]
  lock_args = case unique_args
  when Proc
    unique_args.call(*args)
  when Symbol
    self.send(unique_args, *args)
  else
    args
  end
  "#{lock_key_base}-#{lock_args.to_s}"
end

#lock_key_baseObject



27
28
29
# File 'lib/resque/plugins/better_unique.rb', line 27

def lock_key_base
  "lock:#{name}"
end

#locked?(*args) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/resque/plugins/better_unique.rb', line 31

def locked?(*args)
  Resque.redis.respond_to?(:exists?) ? Resque.redis.exists?(lock_key(*args)) : Resque.redis.exists(lock_key(*args))
end

#release_all_locks(offset = nil) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/resque/plugins/better_unique.rb', line 93

def release_all_locks(offset=nil)
  return if offset == '0'
  new_offset, keys = Resque.redis.scan(offset || 0)
  keys.each do |key|
    Resque.redis.del(key) if key.start_with?(lock_key_base)
  end
  release_all_locks(new_offset)
rescue Redis::CommandError
  Resque.logger.error 'This command only works with versions of redis-server over 2.8'
end

#release_lock(*args) ⇒ Object



81
82
83
# File 'lib/resque/plugins/better_unique.rb', line 81

def release_lock(*args)
  Resque.redis.del(lock_key(*args))
end

#set_lock(*args) ⇒ Object



85
86
87
88
89
90
91
# File 'lib/resque/plugins/better_unique.rb', line 85

def set_lock(*args)
  is_now_locked = Resque.redis.setnx(lock_key(*args), true)
  if is_now_locked && unique_job_options[:timeout]
    Resque.redis.expire(lock_key(*args), unique_job_options[:timeout].to_i)
  end
  is_now_locked
end

#unique_job(mode = :until_executed, options = {}) ⇒ Object



49
50
51
# File 'lib/resque/plugins/better_unique.rb', line 49

def unique_job(mode=:until_executed, **options)
  self.unique_job_options = {mode: mode}.merge(options)
end

#unique_job_modeObject



43
44
45
# File 'lib/resque/plugins/better_unique.rb', line 43

def unique_job_mode
  (unique_job_options[:mode] && unique_job_options[:mode].to_sym) || :none
end

#unique_job_optionsObject



35
36
37
# File 'lib/resque/plugins/better_unique.rb', line 35

def unique_job_options
  @unique_job_options || {}
end

#unique_job_options=(options) ⇒ Object



39
40
41
# File 'lib/resque/plugins/better_unique.rb', line 39

def unique_job_options=(options)
  @unique_job_options = options
end