Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Practical Proc::Daemon example

by jellisii2 (Friar)
on Feb 04, 2014 at 17:51 UTC ( #1073446=perlmeditation: print w/ replies, xml ) Need Help??

I had a lot of trouble getting started with Proc::Daemon because some things weren't completely obvious to me. Here's a practical example that I wrote for practice.

use strict; use warnings; use Getopt::Long; use Proc::Daemon; use Cwd; use File::Spec::Functions; my $pf = catfile(getcwd(), 'pidfile.pid'); my $daemon = Proc::Daemon->new( pid_file => $pf, work_dir => getcwd() ); # are you running? Returns 0 if not. my $pid = $daemon->Status($pf); my $daemonize = 1; GetOptions( 'daemon!' => \$daemonize, "start" => \&run, "status" => \&status, "stop" => \&stop ); sub stop { if ($pid) { print "Stopping pid $pid...\n"; if ($daemon->Kill_Daemon($pf)) { print "Successfully stopped.\n"; } else { print "Could not find $pid. Was it running?\n"; } } else { print "Not running, nothing to stop.\n"; } } sub status { if ($pid) { print "Running with pid $pid.\n"; } else { print "Not running.\n"; } } sub run { if (!$pid) { print "Starting...\n"; if ($daemonize) { # when Init happens, everything under it runs in the child + process. # this is important when dealing with file handles, due to + the fact # Proc::Daemon shuts down all open file handles when Init +happens. # Keep this in mind when laying out your program, particul +arly if # you use filehandles. $daemon->Init; } while (1) { open(my $FH, '>>', catfile(getcwd(), "log.txt")); # any code you want your daemon to run here. # this example writes to a filehandle every 5 +seconds. print $FH "Logging at " . time() . "\n"; close $FH; sleep 5; } } else { print "Already Running with pid $pid\n"; } }

start, stop, and status behave as one would expect. nodaemon runs the daemon in the foreground for troubleshooting. nodaemon must be given before start or it gets ignored.

A little work will need to be done to make it init friendly. This is left as an exercise for the reader.

I'm sure there's better ways to handle the filehandle.

Suggestions are welcome and will be incorporated.

Edit: added catch in stop to not try and stop a daemon that's not running.

Edit: added clarity for what code is actually run when the daemon is running.

Comment on Practical Proc::Daemon example
Select or Download Code
Re: Practical Proc::Daemon example
by Anonymous Monk on Feb 04, 2014 at 22:16 UTC
    Interesting ... could you please note, in the above posting, exactly what was not-obvious to you? It sounds like you ran into, and overcame, some obstacles along the way. Can you please elaborate (outside of the expandable block) just what those were and what you did about it? (Given that your audience hasn't yet run into those rocks, it isn't quite clear from your post just where they are.)

      There is a lack of examples for how to use the module, from my digging. While the documentation is complete, the lack of practical examples made it hard for me to envision how exactly to accomplish what I wished to do. I will freely admit to being spoiled by the great documentation on modules like XML::Twig :D.

      The Init method (still, less so than before, though) has the appearance of voodoo; Timing of its call seems to be very important, particularly if you want to limit the daemon to a single instance, which for my purposes is important as the task that I'm firing is exceptionally cpu intensive and long running. This tripped me up QUITE a few times until I realized I could call Status without having to do an Init. This blindingly bright lightbulb allowed me to get the important stuff (start, stop, status) to behave the way I desired.

      While the terse example on the documentation is valid, it was so far away from my use case (limit to single instance), I couldn't align it with what I wanted to do. The example above was my path to discovery of how to fix my ignorance.

Re: Practical Proc::Daemon example
by Arunbear (Parson) on Feb 05, 2014 at 10:54 UTC
    I like Daemon::Control a lot. If you were using it, none of the above code would be needed (i.e. it takes care of start/stop/status, pid files, init scripts etc). I've even used it to daemonise Java and Python programs.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://1073446]
Approved by moritz
Front-paged by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (14)
As of 2014-10-24 13:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (132 votes), past polls