diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index 7bf6cf02..591946fb 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -210,6 +210,11 @@ module Sidekiq @parent.delete(score, jid) end + def reschedule(at) + @parent.delete(score, jid) + @parent.schedule(at, item) + end + def retry raise "Retry not available on jobs not in the Retry queue." unless item["failed_at"] Sidekiq.redis do |conn| @@ -235,6 +240,12 @@ module Sidekiq Sidekiq.redis {|c| c.zcard(@zset) } end + def schedule(timestamp, message) + Sidekiq.redis do |conn| + conn.zadd(@zset, timestamp.to_s, Sidekiq.dump_json(message)) + end + end + def each(&block) # page thru the sorted set backwards so deleting entries doesn't screw up indexing page = -1 diff --git a/test/test_api.rb b/test/test_api.rb index d4ad08d7..3459e273 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -292,6 +292,22 @@ class TestApi < MiniTest::Unit::TestCase end end + it 'can reschedule jobs' do + add_retry('foo1') + add_retry('foo2') + + retries = Sidekiq::RetrySet.new + assert_equal 2, retries.size + refute(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?) + + retries.each do |retri| + retri.reschedule(Time.now.to_f + 10) if retri.jid == 'foo2' + end + + assert_equal 2, retries.size + assert(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?) + end + def add_retry(jid = 'bob', at = Time.now.to_f) payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' => jid, 'retry_count' => 2, 'failed_at' => Time.now.utc) Sidekiq.redis do |conn|