URLS
http://rubyforge.org/projects/codeforpeople/
http://codeforpeople.com/lib/ruby/lockfile/
SYNOPSIS
lib/lockfile.rb : a ruby library for creating NFS safe lockfiles
bin/rlock : ruby command line tool which uses this library to create
lockfiles
and to run arbitrary commands while holding them.
for example
rlock lockfile -- cp -r huge/ huge.bak/
run 'rlock -h' for more info
INSTALL
sudo ruby install.rb
BASIC ALGORITHIM
-
create a globally uniq filename in the same filesystem as the
desired
lockfile - this can be nfs mounted -
link(2) this file to the desired lockfile, ignore all errors
-
stat the uniq filename and desired lockfile to determine is they
are the
same, use only stat.rdev and stat.ino - ignore stat.nlink as NFS
can cause
this report incorrect values -
iff same, you have lock. either return or run optional code block
with
optional refresher thread keeping lockfile fresh during execution
of code
block, ensuring that the lockfile is removed… -
iff not same try again a few times in rapid succession (poll),
then, iff
this fails, sleep using incremental backoff time. optionally
remove
lockfile if it is older than a certain time, timeout if more than a
certain
amount of time has passed attempting to lock file.
BASIC USAGE
lockfile = Lockfile.new 'file.lock'
begin
lockfile.lock
p 42
ensure
lockfile.unlock
end
require 'pstore' # which is NOT nfs safe on it's own
opts = { # the keys can be symbols or strings
:retries => nil, # we will try forever to aquire the
lock
:sleep_inc => 2, # we will sleep 2 seconds longer than
the
# previous sleep after each retry,
cycling from
# min_sleep upto max_sleep downto
min_sleep upto
# max_sleep, etc., etc.
:min_sleep => 2, # we will never sleep less than 2
seconds
:max_sleep => 32, # we will never sleep longer than 32
seconds
:max_age => 1024, # we will blow away any files found to
be older
# than this (lockfile.thief? #=> true)
:suspend => 64, # iff we steal the lock from someone
else - wait
# this long to give them a chance to
realize it
:refresh => 8, # we will spawn a bg thread that
touches file
# every 8 sec. this thread also causes
a
# StolenLockError to be thrown if the
lock
# disappears from under us - note that
the
# ‘detection’ rate is limited to the
refresh
# interval - this is a race condition
:timeout => nil, # we will wait forever
:poll_retries => 16, # the initial attempt to grab a lock is
done in a
# polling fashion, this number controls
how many
# times this is done - the total
polling attempts
# are considered ONE actual attempt
(see retries
# above)
:poll_max_sleep => 0.08, # when polling a very brief sleep is
issued
# between attempts, this is the upper
limit of
# that sleep timeout
:dont_clean => false, # normally a finalizer is defined to
clean up
# after lockfiles, settin this to true
prevents this
:dont_sweep => false, # normally locking causes a sweep to be
made. a
# sweep removes any old tmp files
created by
# processes of this host only which are
no
# longer alive
:debug => true, # trace execution step on stdout
}
pstore = PStore.new 'file.db'
lockfile = Lockfile.new 'file.db.lock', opts
lockfile.lock do
pstore.transaction do
pstore[:last_update_time] = Time.now
end
end
- same as 1 above - Lockfile.new takes a block and ensures unlock is
called
Lockfile.new('file.lock') do
p 42
end
-
watch locking algorithim in action (debugging only)
Lockfile.debug = true
Lockfile.new(‘file.lock’) do
p 42
end
you can also set debugging via the ENV var LOCKFILE_DEBUG, eg.
~ > LOCKFILE_DEBUG=true rlock lockfile
-
simplified interface : no lockfile object required
Lockfile(‘lock’, :retries => 0) do
puts ‘only one instance running!’
end
SAMPLES
- see samples/a.rb
- see samples/nfsstore.rb
- see samples/lock.sh
- see bin/rlock
AUTHOR
Ara T. Howard
BUGS
bugno > 1 && bugno < 42
HISTORY
1.4.1:
- Mike K. [email protected] reported a bug whereby
false/nil
values for options were ignored. patched to address this bug
- added Lockfile method for high level interface sans lockfile
object
- updated rlock program to allow nil/true/false values passed on
command
line. eg
rlock --max_age=nil lockfile -- date --iso-8601=seconds
enjoy.
-a