Skip to content

Instantly share code, notes, and snippets.

@rtekie
Created October 18, 2011 13:04
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rtekie/1295372 to your computer and use it in GitHub Desktop.
Save rtekie/1295372 to your computer and use it in GitHub Desktop.
Database semaphore mechanism used for example to guarantee that only one instance of a job will run
# Please refer to http://ctoinsights.wordpress.com/2011/10/17/running-distributed-cron-jobs-in-the-cloud/
class DatabaseSemaphore < ActiveRecord::Base
validates_presence_of :name, :message => "can't be blank"
def self.open?(name, lock_duration = 600)
# only one requestor can get open semaphore at a time
# sempahore can be locked in a closed position for lock_duration in seconds
semaphore_open = false
now = Time.now
# insert record if it does not exist yet
DatabaseSemaphore.create(:name => name, :locked_at => now - lock_duration) if !DatabaseSemaphore.find_by_name(name)
DatabaseSemaphore.transaction do
semaphore = DatabaseSemaphore.find_by_name(name, :lock => "LOCK IN SHARE MODE")
if semaphore and semaphore.locked_at <= now - lock_duration
semaphore.locked_at = now
semaphore_open = true if semaphore.save
end
end
return semaphore_open
rescue ActiveRecord::StatementInvalid => e
# deadlock
return false
end
end
class CreateDatabaseSemaphores < ActiveRecord::Migration
def self.up
create_table :database_semaphores do |t|
t.string :name
t.datetime :locked_at
t.timestamps
end
add_index :database_semaphores, :name, :unique => true
end
def self.down
drop_table :database_semaphores
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment