I'm probably late to the game on this, but I stumbled across an
interesting use for DATA. You can use it to ensure only one instance
of a given script is running by using flock:
class Foo
def self.mainloop
while true
puts "Looping..."
sleep 3
end
end
end
DATA.flock(File::LOCK_EX)
if $0 == __FILE__
Foo.mainloop
end
__END_
The first run will work, but trying to start the program up again will
fail instantly because of the lock on DATA. I should probably do some
cleanup there, too, but I thought I'd toss this out there and see if
this is of interest to anyone.
Or was I was recovering from a hangover in college when they mentioned
this trick in class? Anyway, there you go.
On May 20, 2008, at 10:25 PM, Daniel Berger wrote:
The first run will work, but trying to start the program up again will
fail instantly because of the lock on DATA. I should probably do some
cleanup there, too, but I thought I'd toss this out there and see if
this is of interest to anyone.
Or was I was recovering from a hangover in college when they mentioned
this trick in class? Anyway, there you go.
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama
I'm probably late to the game on this, but I stumbled across an
interesting use for DATA. You can use it to ensure only one instance
of a given script is running by using flock:
class Foo
def self.mainloop
while true
puts "Looping..."
sleep 3
end
end
end
Nice one! However, I don't get a failure (on Linux) - instead the
second instance blocks waiting for the first instance to terminate at
which point it executes. Also, needing to specify __END__ is a little
awkward IMHO.
I wonder, does the following work on Windows?
if $0 == __FILE__
if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
Foo.mainloop
end
end
Wrapped up in a method:
$ cat single_instance.rb
def single_instance(&block)
if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
block.call
else
warn "Script #{ $0 } is already running"
end
end
$ cat self_locking.rb
require 'single_instance'
if __FILE__ == $0
single_instance do
Foo.mainloop
end
end
I think I'll use this
Thanks,
Sean
···
On Wed, May 21, 2008 at 5:25 AM, Daniel Berger <djberg96@gmail.com> wrote:
Hi all,
I'm probably late to the game on this, but I stumbled across an
interesting use for DATA. You can use it to ensure only one instance
of a given script is running by using flock:
class Foo
def self.mainloop
while true
puts "Looping..."
sleep 3
end
end
end
DATA.flock(File::LOCK_EX)
if $0 == __FILE__
Foo.mainloop
end
__END_
The first run will work, but trying to start the program up again will
fail instantly because of the lock on DATA. I should probably do some
cleanup there, too, but I thought I'd toss this out there and see if
this is of interest to anyone.
Or was I was recovering from a hangover in college when they mentioned
this trick in class? Anyway, there you go.
However, I wouldn't recommend it's use in any distributed code. flocks
are intended to serve a purpose other than what's achieved as a side
effect here, and although it's generally safe, the behavior is unknown
at best if the script file resides in a remote file system like NFS.
For example, in Linux versions prior to 2.6.12 flocks are local only, so
this would have the intended effect. However, in Linux versions 2.6.12
and newer, flocks are emulated by POSIX locks, which should result in
only a single instance running across a set of machines attempting to
run the same script located in an NFS share.
···
On Wed, May 21, 2008 at 01:25:08PM +0900, Daniel Berger wrote:
The first run will work, but trying to start the program up again will
fail instantly because of the lock on DATA.
On May 20, 10:45 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
On May 20, 2008, at 10:25 PM, Daniel Berger wrote:
> The first run will work, but trying to start the program up again will
> fail instantly because of the lock on DATA. I should probably do some
> cleanup there, too, but I thought I'd toss this out there and see if
> this is of interest to anyone.
> Or was I was recovering from a hangover in college when they mentioned
> this trick in class? Anyway, there you go.
quite interesting, i use self-locking scripts quite often, but DATA is
one step shorter
> I'm probably late to the game on this, but I stumbled across an
> interesting use for DATA. You can use it to ensure only one instance
> of a given script is running by using flock:
> class Foo
> def self.mainloop
> while true
> puts "Looping..."
> sleep 3
> end
> end
> end
> DATA.flock(File::LOCK_EX)
> if $0 == __FILE__
> Foo.mainloop
> end
> __END_
> The first run will work, but trying to start the program up again will
> fail instantly because of the lock on DATA. I should probably do some
> cleanup there, too, but I thought I'd toss this out there and see if
> this is of interest to anyone.
> Or was I was recovering from a hangover in college when they mentioned
> this trick in class? Anyway, there you go.
> Regards,
> Dan
Nice one! However, I don't get a failure (on Linux) - instead the
second instance blocks waiting for the first instance to terminate at
which point it executes. Also, needing to specify __END__ is a little
awkward IMHO.
I wonder, does the following work on Windows?
if $0 == __FILE__
if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
Foo.mainloop
end
end
Wrapped up in a method:
$ cat single_instance.rb
def single_instance(&block)
if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
block.call
else
warn "Script #{ $0 } is already running"
end
end
$ cat self_locking.rb
require 'single_instance'
if __FILE__ == $0
single_instance do
Foo.mainloop
end
end
Yep, that's definitely cleaner, thanks.
I think I'll use this
Excellent. Good to know someone found it useful.
Regards,
Dan
···
On May 25, 7:46 am, "Sean O'Halpin" <sean.ohal...@gmail.com> wrote:
On Wed, May 21, 2008 at 5:25 AM, DanielBerger<djber...@gmail.com> wrote:
It would seem so. Sean O'Halpin has expanded on it a bit, too.
Regards,
Dan
···
On May 20, 11:18 pm, Heesob Park <pha...@gmail.com> wrote:
DanielBergerwrote:
> Hi all,
> I'm probably late to the game on this, but I stumbled across an
> interesting use for DATA. You can use it to ensure only one instance
> of a given script is running by using flock:
> class Foo
> def self.mainloop
> while true
> puts "Looping..."
> sleep 3
> end
> end
> end
However, I wouldn't recommend it's use in any distributed code. flocks
are intended to serve a purpose other than what's achieved as a side
effect here, and although it's generally safe, the behavior is unknown
at best if the script file resides in a remote file system like NFS.
For example, in Linux versions prior to 2.6.12 flocks are local only, so
this would have the intended effect. However, in Linux versions 2.6.12
and newer, flocks are emulated by POSIX locks, which should result in
only a single instance running across a set of machines attempting to
run the same script located in an NFS share.
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama
Apparently so, because it was a use.perl blog entry that gave me the
idea. For whatever reason I never came across that idiom even while I
was mainly a Perl guy.
Regards,
Dan
···
On May 25, 11:43 am, "Xavier Noria" <f...@hashref.com> wrote:
On Wed, May 21, 2008 at 7:08 AM, Joel VanderWerf > > <vj...@path.berkeley.edu> wrote:
> DanielBergerwrote:
>> DATA.flock(File::LOCK_EX)
> Google seems to think it's original, FWIW.
Locking DATA has been used in Perl for a long time.
I was able to find 0.0.1 via the RAA, though. Is that the latest
version? I ask because I want to build from source.
Thanks,
Dan
···
On May 28, 5:48 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
On May 28, 2008, at 4:35 PM, Mike Kasick wrote:
> Cute trick.
> However, I wouldn't recommend it's use in any distributed code.
> flocks
> are intended to serve a purpose other than what's achieved as a side
> effect here, and although it's generally safe, the behavior is unknown
> at best if the script file resides in a remote file system like NFS.
> For example, in Linux versions prior to 2.6.12 flocks are local
> only, so
> this would have the intended effect. However, in Linux versions
> 2.6.12
> and newer, flocks are emulated by POSIX locks, which should result in
> only a single instance running across a set of machines attempting to
> run the same script located in an NFS share.
you can use the same trick even on NFS
require 'posixlock' # gem installposixlock
DATA.posixlock( File::LOCK_EX | File::LOCK_NB )
and this will work for both NFS and local fs. of course you'd need to
degrade to flock ifposixlockis not installed....
my lockfile gem is also NFS safe and can be used for this purpose.
actually it can make any program run one instance without modification