Skip to content

Instantly share code, notes, and snippets.

@josephglanville
Last active December 26, 2015 20:58
Show Gist options
  • Save josephglanville/7212371 to your computer and use it in GitHub Desktop.
Save josephglanville/7212371 to your computer and use it in GitHub Desktop.
Simple atomic locks and Master Election with RethinkDB and Celluloid
require 'rethinkdb'
require 'celluloid'
include RethinkDB::Shortcuts
LOCK_TIMEOUT = 15
UPDATE_TIMEOUT = 5
r.connect.repl
r.branch(r.table_list.contains('locks'),
r.expr(created: 1),
r.table_create('locks')).run
class MasterElectionExample
include Celluloid
attr_reader :is_master
def initialize
@is_master = false
request_master_election
@timer = every(UPDATE_TIMEOUT) do
if @is_master
puts 'i am the master, updating lock'
update_lock 'master'
else
request_master_election
end
end
end
def aquire_lock?(lock_name)
res = r.branch(r.table('locks').get(lock_name),
r.do(r.table('locks').get(lock_name)) {|lock|
r.branch(lock[:time] > (r.now - LOCK_TIMEOUT),
r.expr(unchanged: 1, replaced: 0, inserted: 0),
r.table('locks').replace(id: lock_name, time: r.now))},
r.table('locks').insert(id: lock_name, time: r.now)
).run
res['inserted'] == 1 || res['replaced'] == 1
end
def update_lock(lock_name)
r.table('locks').update({id: lock_name, time: r.now}).run
end
def request_master_election
if aquire_lock? 'master'
@is_master = true
puts 'i am the master. :)'
else
@is_master = false
puts 'i am not the master. :('
end
end
end
class MasterGroup < Celluloid::SupervisionGroup
supervise MasterElectionExample, as: :actor
end
MasterGroup.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment