Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wereHamster
Created April 18, 2011 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wereHamster/925159 to your computer and use it in GitHub Desktop.
Save wereHamster/925159 to your computer and use it in GitHub Desktop.
# begin
# if lock = Lock.acquire('indexing')
# ...
# end
# ensure
# lock.release if lock
# end
# Host: MacBook 2.4GHz Core 2 Duo
# Sqlite -> 120 acquires+unlocks per second
# MySQL -> ???
class Lock < ActiveRecord::Base
# Find the lock with the given name and aquire it. If successful, return
# the lock object (so we can later unlock it), otherwise nil
def self.acquire(name)
lock = self.find_or_create_by_name(name)
return lock.acquire() && lock || nil
end
# Ackquire the lock. Return a boolean indicating whether we own the lock
# or not.
def acquire
return self.class.update_all([
"time = ?, owner = ?", Time.now, self.class.owner
], [
"name = ? AND owner IS NULL", name]
) == 1
end
# Release the lock.
def release
return self.class.update_all([
"time = ?, owner = NULL", Time.now
], [
"name = ? AND owner = ?", name, self.class.owner]
) == 1
end
private
# We use a combination of hostname and PID to identify ourselves. This
# makes it easy to identify the exact process who holds the lock in case
# something goes wrong (the process crashes).
def self.owner
return "#{Socket.gethostname}:#{Process.pid}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment