Lockfile-1.4.1

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
  1. same as 1 above - Lockfile.new takes a block and ensures unlock is
    called
 Lockfile.new('file.lock') do
   p 42
 end
  1. 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
  1. 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

EMAIL

[email protected]

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

Ara.T.Howard wrote:

SYNOPSIS

lib/lockfile.rb : a ruby library for creating NFS safe lockfiles

Can this be used to get around a broken NFS lock configuration
like I have on our branch’s cluster?

Later,