[ANN] 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

   1)
     lockfile = Lockfile.new 'file.lock'
     begin
       lockfile.lock
       p 42
     ensure
       lockfile.unlock
     end

   2)
     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

   3) same as 1 above - Lockfile.new takes a block and ensures unlock is called

     Lockfile.new('file.lock') do
       p 42
     end

   4) 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

   5) 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

   Ara.T.Howard@noaa.gov

BUGS

   bugno > 1 && bugno < 42

HISTORY

   1.4.1:
     - Mike Kasick <mkasick@club.cc.cmu.edu> 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

···

--
in the practice of tolerance, one's enemy is the best teacher.
- the dalai lama

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,

···

--
Bil Kleb
http://fun3d.larc.nasa.gov

I didn't think that locking on nfs was ever really all that safe. I've
seen it fail too often.

Mike

···

On 1/5/07, Bil Kleb <Bil.Kleb@nasa.gov> wrote:

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?

--
Michael P. Soulier <msoulier@digitaltorque.ca>
"Any intelligent fool can make things bigger and more complex... It takes a
touch of genius - and a lot of courage to move in the opposite direction."
--Albert Einstein