SYNOPSIS lib/lockfile.rb : ruby library for creating NFS safe lockfiles bin/rlock : ruby command line tool which uses this library to create lockfiles. 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, 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 lock_opts = { # the keys can be symbols or strings :retries => 42, # we will try 42 times to aquire the lock :sleep_inc => 2, # we will sleep 2 seconds longer after each retry :max_sleep => 30, # we will never sleep longer than 30 seconds however :max_age => 3600, # we will blow away any files older than this :suspend => 16, # 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' is limited to the poll interval :timeout => 300 # we simply cannot wait longer than five minutes } 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 SAMPLES * see samples/a.rb * see samples/nfsstore.rb * see bin/rlock