Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow jobs to be queuable once the existing job starts performing #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,22 @@ UpdateNetworkGraph is queued at a time, regardless of the
repo_id. Normally a job is locked using a combination of its
class name and arguments.

If you don't want to have to wait until a job has completed
before being able to enqueue another job with the same
arguments, you can set the `unlock_while_performing` flag:

class UpdateNetworkGraph
extend Resque::Plugins::Lock
@unlock_while_performing = true

# etc ...
end

With this option set, another job of the same type with the
same arguments can be queued even while the original one is
being performed. Otherwise, the queue will remain locked
until the job has completed. This option can be useful if you
know that some data has changed which the currently-performing
job will not have taken into account.

[rq]: http://github.com/defunkt/resque
4 changes: 4 additions & 0 deletions lib/resque/plugins/lock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ def before_enqueue_lock(*args)
now > Resque.redis.getset(key, timeout).to_i
end

def before_perform_lock(*args)
Resque.redis.del(lock(*args)) if @unlock_while_performing
end

def around_perform_lock(*args)
begin
yield
Expand Down
38 changes: 38 additions & 0 deletions test/lock_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def self.perform
def setup
Resque.redis.del('queue:lock_test')
Resque.redis.del(Job.lock)
Resque.redis.del(JobWithOptionalQueueOnlyLocking.lock)
end

def test_lint
Expand Down Expand Up @@ -57,4 +58,41 @@ def test_deadlock
Resque.enqueue(Job)
assert_equal 2, Resque.redis.llen('queue:lock_test')
end

class JobWithOptionalQueueOnlyLocking
extend Resque::Plugins::Lock
@queue = :lock_test
class << self
attr_accessor :unlock_while_performing
end

def self.perform
Resque.enqueue(self)
if unlock_while_performing
raise 'this job should be queueable while it is running' unless
Resque.redis.llen('queue:lock_test') == 1
else
raise 'this job should NOT be queueable while it is running' unless
Resque.redis.llen('queue:lock_test') == 0
end
end
end

def test_queue_is_normally_locked_when_job_running
JobWithOptionalQueueOnlyLocking.unlock_while_performing = nil
Resque.enqueue(JobWithOptionalQueueOnlyLocking)
job = Resque.reserve('lock_test')
job.perform
rescue => e
flunk e.message
end

def test_queue_only_locking
JobWithOptionalQueueOnlyLocking.unlock_while_performing = true
Resque.enqueue(JobWithOptionalQueueOnlyLocking)
job = Resque.reserve('lock_test')
job.perform
rescue => e
flunk e.message
end
end