Skip to content

Commit 61a8ed0

Browse files
Joel Lubranojeremy
authored andcommitted
Ensure that jobs are directly created for jobs enqueued at Time.now
If less than a second passes between calling Resque.enqueue_in(0, ...), which is not all that unlikely, a job may be delayed when we don't expect the job to be delayed. In high traffic applications where the resque scheduler process is very busy, this unexpected delay can grow as other jobs are being enqueued after their own delays. Since resque-scheduler only supports multiple instances for redundancy, there is no way to scale resque-scheduler horizontally. Thus my goal is to ensure that as many jobs as possible are created directly and not unexpectedly delayed.
1 parent 1787c6a commit 61a8ed0

File tree

5 files changed

+12
-3
lines changed

5 files changed

+12
-3
lines changed

lib/resque/scheduler/delaying_extensions.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def enqueue_at(timestamp, klass, *args)
2424
def enqueue_at_with_queue(queue, timestamp, klass, *args)
2525
return false unless plugin.run_before_schedule_hooks(klass, *args)
2626

27-
if Resque.inline? || timestamp.to_i < Time.now.to_i
27+
if Resque.inline? || timestamp.to_i <= Time.now.to_i
2828
# Just create the job and let resque perform it right away with
2929
# inline. If the class is a custom job class, call self#scheduled
3030
# on it. This allows you to do things like

resque-scheduler.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Gem::Specification.new do |spec|
4848
spec.add_development_dependency 'test-unit'
4949
spec.add_development_dependency 'yard'
5050
spec.add_development_dependency 'tzinfo-data'
51+
spec.add_development_dependency 'timecop'
5152

5253
# We pin rubocop because new cops have a tendency to result in false-y
5354
# positives for new contributors, which is not a nice experience.

test/delayed_queue_test.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@
285285
Resque.enqueue_at(Time.now - 10, SomeFancyJob, 'foo', 'bar')
286286
end
287287

288+
test 'enqueue_at calls Resque#enqueue when given the current time' do
289+
Timecop.freeze do
290+
Resque.expects(:enqueue_to).with(:fancy, SomeFancyJob, 'foo', 'bar')
291+
Resque.enqueue_at(Time.now, SomeFancyJob, 'foo', 'bar')
292+
end
293+
end
294+
288295
test 'enqueue_next_item picks one job' do
289296
t = Time.now + 60
290297

test/scheduler_hooks_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
setup { Resque.data_store.redis.flushall }
66

77
test 'before_schedule hook that does not return false should be enqueued' do
8-
enqueue_time = Time.now
8+
enqueue_time = Time.now + 1
99
SomeRealClass.expects(:before_schedule_example).with(:foo)
1010
SomeRealClass.expects(:after_schedule_example).with(:foo)
1111
Resque.enqueue_at(enqueue_time.to_i, SomeRealClass, :foo)
@@ -14,7 +14,7 @@
1414
end
1515

1616
test 'before_schedule hook that returns false should not be enqueued' do
17-
enqueue_time = Time.now
17+
enqueue_time = Time.now + 1
1818
SomeRealClass.expects(:before_schedule_example).with(:foo).returns(false)
1919
SomeRealClass.expects(:after_schedule_example).never
2020
Resque.enqueue_at(enqueue_time.to_i, SomeRealClass, :foo)

test/test_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require 'mocha/setup'
77
require 'rack/test'
88
require 'resque'
9+
require 'timecop'
910

1011
$LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__)) + '/../lib'
1112
require 'resque-scheduler'

0 commit comments

Comments
 (0)