[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

proper way to daemonize

Tim Pease

4/24/2009 3:11:00 PM

module Process
def self.daemon( nochdir = nil, noclose = nil )
exit if fork # Parent exits, child continues.
Process.setsid # Become session leader.
exit if fork # Zap session leader.

unless nochdir
Dir.chdir "/" # Release old working directory.
end

File.umask 0000 # Ensure sensible umask. Adjust as needed.

unless noclose
STDIN.reopen "/dev/null" # Free file descriptors and
STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
STDERR.reopen '/dev/null', 'a'
end

return 0
end
end


This is the standard code to daemonize a process. The use of "exit"
bothers me slightly, as it will call all "at_exit" handlers in the
parent. I do not believe this is the desired behavior; the "at_exit"
handlers will free resources that the daemonized process might need.
Instead, "exit!" should be used to prevent "at_exit" handlers from
being called.

Any thoughts about this subtle change? Are there any undesirable side
effects that arise from using exit! instead of exit ?

Blessings,
TwP

11 Answers

Gary Wright

4/24/2009 4:01:00 PM

0


On Apr 24, 2009, at 11:11 AM, Tim Pease wrote:
>
> This is the standard code to daemonize a process. The use of "exit"
> bothers me slightly, as it will call all "at_exit" handlers in the
> parent. I do not believe this is the desired behavior; the "at_exit"
> handlers will free resources that the daemonized process might need.

What resources are you talking about? By the time exit is called, the
process has already been duplicated. The child process won't be
affected
by anything the parent does during via at_exit processing (at least
with respect to Ruby object resources).


James Gray

4/24/2009 4:12:00 PM

0

On Apr 24, 2009, at 11:01 AM, Gary Wright wrote:

> On Apr 24, 2009, at 11:11 AM, Tim Pease wrote:
>>
>> This is the standard code to daemonize a process. The use of "exit"
>> bothers me slightly, as it will call all "at_exit" handlers in the
>> parent. I do not believe this is the desired behavior; the "at_exit"
>> handlers will free resources that the daemonized process might need.
>
> What resources are you talking about? By the time exit is called, the
> process has already been duplicated. The child process won't be =20
> affected
> by anything the parent does during via at_exit processing (at least
> with respect to Ruby object resources).

But if that at_exit() handler deletes a file or something=85

Anyway, I do use exit!() in my daemonize() method.

James Edward Gray II=

Gary Wright

4/24/2009 4:41:00 PM

0


On Apr 24, 2009, at 12:11 PM, James Gray wrote:

> On Apr 24, 2009, at 11:01 AM, Gary Wright wrote:
>
>> On Apr 24, 2009, at 11:11 AM, Tim Pease wrote:
>>>
>>> This is the standard code to daemonize a process. The use of "exit"
>>> bothers me slightly, as it will call all "at_exit" handlers in the
>>> parent. I do not believe this is the desired behavior; the "at_exit"
>>> handlers will free resources that the daemonized process might need.
>>
>> What resources are you talking about? By the time exit is called, =20=

>> the
>> process has already been duplicated. The child process won't be =20
>> affected
>> by anything the parent does during via at_exit processing (at least
>> with respect to Ruby object resources).
>
> But if that at_exit() handler deletes a file or something=85


Well, that is why I put the caveat about 'Ruby object resources'.
Isn't it fair to assume the at_exit code isn't actively hostile? :-)

If you've got at_exit() code that is trashing external resources that =20=

are used by a child process, that is a bug to be fixed I think rather =20=

than a bug to be obscured via exit!=

Tim Pease

4/24/2009 5:19:00 PM

0

On Fri, Apr 24, 2009 at 10:40 AM, Gary Wright <gwtmp01@mac.com> wrote:
>
> On Apr 24, 2009, at 12:11 PM, James Gray wrote:
>
>> On Apr 24, 2009, at 11:01 AM, Gary Wright wrote:
>>
>>> On Apr 24, 2009, at 11:11 AM, Tim Pease wrote:
>>>>
>>>> This is the standard code to daemonize a process. The use of "exit"
>>>> bothers me slightly, as it will call all "at_exit" handlers in the
>>>> parent. I do not believe this is the desired behavior; the "at_exit"
>>>> handlers will free resources that the daemonized process might need.
>>>
>>> What resources are you talking about? =A0By the time exit is called, th=
e
>>> process has already been duplicated. =A0The child process won't be affe=
cted
>>> by anything the parent does during via at_exit processing (at least
>>> with respect to Ruby object resources).
>>
>> But if that at_exit() handler deletes a file or something=85
>
>
> Well, that is why I put the caveat about 'Ruby object resources'.
> Isn't it fair to assume the at_exit code isn't actively hostile? :-)
>
> If you've got at_exit() code that is trashing external resources that are
> used by a child process, that is a bug to be fixed I think rather than a =
bug
> to be obscured via exit!
>

Yes, I am using an at_exit hook to close out file descriptors used by
loggers. Part of this close out process is writing out some diagnostic
messages to the loggers. These at_exit hooks need to be called when
the child process exits, not when the parent process exits.

The two solutions are:

1) daemonize is the VERY FIRST thing the program should do before any
initialization is run
2) daemonize should use exit! if initialization needs to be performed
before daemonizing

Anyway, it sounds like James is using exit! without ill affect. /me
heads in that direction.

Blessings,
TwP

Robert Dober

4/24/2009 6:44:00 PM

0

On Fri, Apr 24, 2009 at 6:40 PM, Gary Wright <gwtmp01@mac.com> wrote:

> Well, that is why I put the caveat about 'Ruby object resources'.
> Isn't it fair to assume the at_exit code isn't actively hostile? :-)
Well I do see the smiley but still want to point out that "passively
hostile" might be bad enough, actually pretty bad!
>
> If you've got at_exit() code that is trashing external resources that are
> used by a child process, that is a bug to be fixed I think rather than a =
bug
> to be obscured via exit!
This is a good point though, I guess bombing in the child might indeed
be the best way to find out what is conceptually wrong, but I am quite
unexperienced with this kind of code in Ruby. OTOH are not most of us?

Cheers
Robert



--=20
Si tu veux construire un bateau ...
Ne rassemble pas des hommes pour aller chercher du bois, pr=E9parer des
outils, r=E9partir les t=E2ches, all=E9ger le travail=85 mais enseigne aux
gens la nostalgie de l=92infini de la mer.

If you want to build a ship, don=92t herd people together to collect
wood and don=92t assign them tasks and work, but rather teach them to
long for the endless immensity of the sea.

--
Antoine de Saint-Exup=E9ry

Eric Hodel

4/24/2009 6:47:00 PM

0

On Apr 24, 2009, at 08:11, Tim Pease wrote:
> # ...
>
> This is the standard code to daemonize a process. The use of "exit"
> bothers me slightly, as it will call all "at_exit" handlers in the
> parent. I do not believe this is the desired behavior; the "at_exit"
> handlers will free resources that the daemonized process might need.
> Instead, "exit!" should be used to prevent "at_exit" handlers from
> being called.
>
> Any thoughts about this subtle change? Are there any undesirable side
> effects that arise from using exit! instead of exit ?

Why not just:

require 'webrick/server'

WEBrick::Dameon.start

It has exit! and all that built-in.

Tim Pease

4/24/2009 7:08:00 PM

0

On Fri, Apr 24, 2009 at 12:46 PM, Eric Hodel <drbrain@segment7.net> wrote:
> On Apr 24, 2009, at 08:11, Tim Pease wrote:
>>
>> # ...
>>
>> This is the standard code to daemonize a process. The use of "exit"
>> bothers me slightly, as it will call all "at_exit" handlers in the
>> parent. I do not believe this is the desired behavior; the "at_exit"
>> handlers will free resources that the daemonized process might need.
>> Instead, "exit!" should be used to prevent "at_exit" handlers from
>> being called.
>>
>> Any thoughts about this subtle change? Are there any undesirable side
>> effects that arise from using exit! instead of exit ?
>
> Why not just:
>
> require 'webrick/server'
>
> WEBrick::Dameon.start
>
> It has exit! and all that built-in.
>

Eric, if I had half your brain I'd be twice as smart. Didn't even
think to look through the stdlibs.

Sinatra and Rails use the plain old "exit" in their flavor of the
daemon method. This is causing issues with closing out log files
prematurely. Just getting a consensus from the wider ruby community
about the _correct_ behavior.

Blessings,
TwP

James Gray

4/24/2009 7:12:00 PM

0

On Apr 24, 2009, at 2:07 PM, Tim Pease wrote:

> On Fri, Apr 24, 2009 at 12:46 PM, Eric Hodel <drbrain@segment7.net>
> wrote:
>> On Apr 24, 2009, at 08:11, Tim Pease wrote:
>>>
>>> # ...
>>>
>>> This is the standard code to daemonize a process. The use of "exit"
>>> bothers me slightly, as it will call all "at_exit" handlers in the
>>> parent. I do not believe this is the desired behavior; the "at_exit"
>>> handlers will free resources that the daemonized process might need.
>>> Instead, "exit!" should be used to prevent "at_exit" handlers from
>>> being called.
>>>
>>> Any thoughts about this subtle change? Are there any undesirable
>>> side
>>> effects that arise from using exit! instead of exit ?
>>
>> Why not just:
>>
>> require 'webrick/server'
>>
>> WEBrick::Dameon.start
>>
>> It has exit! and all that built-in.
>>
>
> Eric, if I had half your brain I'd be twice as smart. Didn't even
> think to look through the stdlibs.

As of Ruby 1.9 Process.daemon() is a core method. Just one more
reason 1.9 rocks. :)

James Edward Gray II


James Gray

4/24/2009 7:18:00 PM

0

On Apr 24, 2009, at 11:40 AM, Gary Wright wrote:
>
> On Apr 24, 2009, at 12:11 PM, James Gray wrote:
>
>> On Apr 24, 2009, at 11:01 AM, Gary Wright wrote:
>>
>>> On Apr 24, 2009, at 11:11 AM, Tim Pease wrote:
>>
>>>
>>>> This is the standard code to daemonize a process. The use of "exit"
>>>> bothers me slightly, as it will call all "at_exit" handlers in the
>>>> parent. I do not believe this is the desired behavior; the =20
>>>> "at_exit"
>>>> handlers will free resources that the daemonized process might =20
>>>> need.
>>>
>>> What resources are you talking about? By the time exit is called, =20=

>>> the
>>> process has already been duplicated. The child process won't be =20
>>> affected
>>> by anything the parent does during via at_exit processing (at least
>>> with respect to Ruby object resources).
>>
>> But if that at_exit() handler deletes a file or something=85
>
>
> Well, that is why I put the caveat about 'Ruby object resources'.
> Isn't it fair to assume the at_exit code isn't actively hostile? :-)
>
> If you've got at_exit() code that is trashing external resources =20
> that are used by a child process, that is a bug to be fixed I think =20=

> rather than a bug to be obscured via exit!

Seems like Tim has a pretty decent example where the behavior doesn't =20=

feel buggy.

Basically, I view it this way. The exit() calls in a daemonize() =20
method aren't the typical usage. Normally, exit() is used to end a =20
process. Our process isn't really ending though so much as =20
transitioning into a different kind of process. exit() is just an =20
implementation detail of how that transition occurs. As such, exit!() =20=

feels more correct to me because I don't want to go through a shutdown =20=

sequence of the original process, I just want the first to immediately =20=

cease to exist while the second takes over for it.

That's all just my opinion though. Feel free to ignore.

James Edward Gray II


Gary Wright

4/24/2009 10:53:00 PM

0


On Apr 24, 2009, at 3:17 PM, James Gray wrote:
> Seems like Tim has a pretty decent example where the behavior
> doesn't feel buggy.

I wouldn't call it buggy, but calling at_exit in a process that
shouldn't execute the block seems premature. Better to wait and call
it in the forked child process, I think.

It looks like 1.9's Process.daemon uses exit! and it doesn't look like
it does a double-fork which is a best-practice sort of thing (in order
to avoid acquiring a new controlling terminal). I suppose I should
open a ticket...

Gary Wright