[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ensuring only one instance of a script is running

Daniel Berger

5/21/2008 4:25:00 AM

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.

Regards,

Dan

13 Answers

ara.t.howard

5/21/2008 4:46:00 AM

0




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

thanks for the tip.

a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Joel VanderWerf

5/21/2008 5:08:00 AM

0

Daniel Berger wrote:
> DATA.flock(File::LOCK_EX)

Google seems to think it's original, FWIW.

It's kind of unusual for a new ruby idiom to show up. Yippee.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Heesob Park

5/21/2008 5:19:00 AM

0

Daniel Berger 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)
I think the above is actually equal to

File.new($0).flock(File::LOCK_EX)


Regards,

Park Heesob
--
Posted via http://www.ruby-....

Daniel Berger

5/21/2008 1:41:00 PM

0



On May 20, 10:45=A0pm, "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 =A0=

> one step shorter ;-)
>
> thanks for the tip.

You're welcome. :)

I've wasted a lot of time with pid files...

Regards,

Dan

Jos Backus

5/24/2008 8:01:00 PM

0

On Wed, May 21, 2008 at 10:40:49PM +0900, Daniel Berger wrote:
> I've wasted a lot of time with pid files...

Hear hear. You could also use a process manager such as daemontools or runit -
that's generally what I do.

--
Jos Backus
jos at catnook.com

Sean O'Halpin

5/25/2008 1:46:00 PM

0

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.
>
> 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

I think I'll use this :)

Thanks,
Sean

Xavier Noria

5/25/2008 5:43:00 PM

0

On Wed, May 21, 2008 at 7:08 AM, Joel VanderWerf
<vjoel@path.berkeley.edu> wrote:
> Daniel Berger wrote:
>>
>> DATA.flock(File::LOCK_EX)
>
> Google seems to think it's original, FWIW.

Locking DATA has been used in Perl for a long time.

Daniel Berger

5/28/2008 6:31:00 PM

0

On May 25, 11:43=A0am, "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.

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

Daniel Berger

5/28/2008 6:33:00 PM

0



On May 25, 7:46=A0am, "Sean O'Halpin" <sean.ohal...@gmail.com> wrote:
> On Wed, May 21, 2008 at 5:25 AM, DanielBerger<djber...@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
> > =A0 def self.mainloop
> > =A0 =A0 =A0while true
> > =A0 =A0 =A0 =A0 puts "Looping..."
> > =A0 =A0 =A0 =A0 sleep 3
> > =A0 =A0 =A0end
> > =A0 end
> > end
>
> > DATA.flock(File::LOCK_EX)
>
> > if $0 =3D=3D __FILE__
> > =A0 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 =3D=3D __FILE__
> =A0 if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
> =A0 =A0 Foo.mainloop
> =A0 end
> end
>
> Wrapped up in a method:
>
> $ cat single_instance.rb
> def single_instance(&block)
> =A0 if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
> =A0 =A0 block.call
> =A0 else
> =A0 =A0 warn "Script #{ $0 } is already running"
> =A0 end
> end
>
> $ cat self_locking.rb
> require 'single_instance'
> if __FILE__ =3D=3D $0
> =A0 single_instance do
> =A0 =A0 Foo.mainloop
> =A0 end
> end

Yep, that's definitely cleaner, thanks.

> I think I'll use this :)

Excellent. Good to know someone found it useful. :)

Regards,

Dan

Daniel Berger

5/28/2008 6:35:00 PM

0



On May 20, 11:18=A0pm, 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
> > =A0 =A0def self.mainloop
> > =A0 =A0 =A0 while true
> > =A0 =A0 =A0 =A0 =A0puts "Looping..."
> > =A0 =A0 =A0 =A0 =A0sleep 3
> > =A0 =A0 =A0 end
> > =A0 =A0end
> > end
>
> > DATA.flock(File::LOCK_EX)
>
> I think the above is actually equal to
>
> File.new($0).flock(File::LOCK_EX)

It would seem so. Sean O'Halpin has expanded on it a bit, too.

Regards,

Dan