# Lockfile-1.4.1

**URL:** <https://www.ruby-forum.com/t/lockfile-1-4-1/81208>\
**Category:** Ruby\
**Created:** [January 6, 2007, 7:18pm UTC](https://www.ruby-forum.com/t/lockfile-1-4-1/81208 "2007-01-06T19:18:58Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 6, 2007, 7:18pm UTC](https://www.ruby-forum.com/t/lockfile-1-4-1/81208/1 "2007-01-06T19:18:58Z")

</div>

URLS

[http://rubyforge.org/projects/codeforpeople/](http://rubyforge.org/projects/codeforpeople/)  
[http://codeforpeople.com/lib/ruby/lockfile/](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

```

1. 

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

```
 you can also set debugging via the ENV var LOCKFILE_DEBUG, eg.

 ~ > LOCKFILE_DEBUG=true rlock lockfile

```

1. simplified interface : no lockfile object required

SAMPLES

- see samples/a.rb
- see samples/nfsstore.rb
- see samples/lock.sh
- see bin/rlock

AUTHOR

Ara T. Howard

EMAIL

removed\_email\_address@domain.invalid

BUGS

bugno \> 1 && bugno \< 42

HISTORY

1.4.1:  
- Mike K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [September 25, 2007, 10:48pm UTC](https://www.ruby-forum.com/t/lockfile-1-4-1/81208/2 "2007-09-25T22:48:36Z")

</div>

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,
