Skip to content
Closed
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
10 changes: 9 additions & 1 deletion lib/mega_mutex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,16 @@ def self.get_current_lock(mutex_id)
# with_distributed_mutex('my_mutex_id_1234', :timeout => 20) do
# do_something!
# end
#
# Additionally, you can specify the amount of time the lock should be valid
# for. This is helpful in preventing deadlocks when the lock isn't deleted
# for whatever reason.
#
# with_distributed_mutex('my_mutex_id_1234', :ttl => 20) do
# do_something!
# end
def with_distributed_mutex(mutex_id, options = {}, &block)
mutex = DistributedMutex.new(mutex_id, options[:timeout])
mutex = DistributedMutex.new(mutex_id, options[:timeout], options[:ttl])
begin
mutex.run(&block)
rescue Object => e
Expand Down
5 changes: 3 additions & 2 deletions lib/mega_mutex/distributed_mutex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ def cache
end
end

def initialize(key, timeout = nil)
def initialize(key, timeout = nil, ttl = nil)
@key = key
@timeout = timeout
@ttl = ttl
end

def logger
Expand Down Expand Up @@ -74,7 +75,7 @@ def locked_by_me?
end

def set_current_lock(new_lock)
cache.add(@key, my_lock_id)
cache.add(@key, my_lock_id, @ttl)
end

def my_lock_id
Expand Down
20 changes: 20 additions & 0 deletions spec/lib/mega_mutex_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,25 @@ def mutex_id
assert @exception.is_a?(MegaMutex::TimeoutError), "Expected TimeoutError to be raised, but wasn't"
end
end

describe 'with a TTL' do
it "should release the lock after the TTL has expired" do
messages = []

threads << Thread.new do
with_distributed_mutex('foo', :ttl => 0.2) do
sleep 0.4
messages << 'Second message'
end
end
threads << Thread.new do
with_distributed_mutex('foo') { messages << 'First message' }
end

wait_for_threads_to_finish
messages.first.should eq('First message')
messages.first.should eq('Second message')
end
end
end
end