How do I ensure only one instance of a Ruby script is running at a time?

I know this is old, but for anyone interested, there's a non-blocking constant that you can pass to flock so that it returns instead of blocking.

File.new("/tmp/foo.lock").flock( File::LOCK_NB | File::LOCK_EX )

Update for slhck

flock will return true if this process received the lock, false otherwise. So to ensure just one process is running at a time you just want to try to get the lock, and exit if you weren't able to. It's as simple as putting an exit unless in front of the line of code I have above:

exit unless File.new("/tmp/foo.lock").flock( File::LOCK_NB | File::LOCK_EX )

Although this isn't directly answering your question, if I were you I'd probably write a daemon script (you could use http://daemons.rubyforge.org/)

You could have your indexer (assuming its indexer.rb) be run through a wrapper script named script/index for example:

require 'rubygems'
require 'daemons'

Daemons.run('indexer.rb')

And your indexer can do almost the same thing, except you specify a sleep interval

loop do
   # code executing your indexing 

   sleep INDEXING_INTERVAL
end

This is how job processors in tandem with a queue server usually function.


You could create and delete a temporary file and check for existence of this file. Please check the answer to this question : one instance shell script


Depending on your needs, this should work just fine and doesn't require creating another file anywhere.

exit unless DATA.flock(File::LOCK_NB | File::LOCK_EX)

# your script here

__END__
DO NOT REMOVE: required for the DATA object above.

Tags:

Linux

Ruby