module Ohm::Locking

This module is a straight extraction from Ohm. The only difference is that this allows for a custom sleep value.

In addition, since future ohm versions might drop mutexes, I thought it might be a good idea to preseve this feature as a drop-in module.

Public Instance Methods

spinlock(wait = 0.1) { || ... } click to toggle source

Lock the object before executing the block, and release it once the block is done.

post = Order.create(customer: Customer.create)
post.mutex(0.01) do
  # this block is in a mutex!
end
# File lib/ohm/locking.rb, line 15
def spinlock(wait = 0.1)
  lock!(wait)
  yield
ensure
  unlock!
end

Protected Instance Methods

lock!(wait = 0.1) click to toggle source

Lock the object so no other instances can modify it. This method implements the design pattern for locks described at: code.google.com/p/redis/wiki/SetnxCommand

@see Model#mutex

# File lib/ohm/locking.rb, line 28
def lock!(wait = 0.1)
  until redis.call("SETNX", key[:_lock], lock_timeout) == 1
    next unless lock = redis.call("GET", key[:_lock])
    sleep(wait) and next unless lock_expired?(lock)

    break unless lock = redis.call("GETSET", key[:_lock], lock_timeout)
    break if lock_expired?(lock)
  end
end
lock_expired?(lock) click to toggle source
# File lib/ohm/locking.rb, line 48
def lock_expired?(lock)
  lock.to_f < Time.now.to_f
end
lock_timeout() click to toggle source
# File lib/ohm/locking.rb, line 44
def lock_timeout
  Time.now.to_f + 1
end
unlock!() click to toggle source

Release the lock. @see Model#mutex

# File lib/ohm/locking.rb, line 40
def unlock!
  redis.call("DEL", key[:_lock])
end