gh has asked for the wisdom of the Perl Monks concerning the following question:

I have a daemon using Daemon::Control, and would like my app to test whether it's running, so it can gracefully fail over if not.

My current solution is to open a UNIX subshell and pipe using '-|' to "daemon.pl status", and test if the output says "Not Running" or "Running". Not very elegant, and inefficient.

I tried a Daemon::Control->new(...)->do_status with the same parameters as the daemon, but it says "Not Running" always, presumably because the executable is different.

I could check the pid file, look at /proc/<pid> and see if it looks like the daemon with a bunch of tests. But this seems like the sort of thing a daemon library should simply provide.

So is there a direct way using just Perl to test for this?

  • Comment on Test if Daemon::Control daemon is running.

Replies are listed 'Best First'.
Re: Test if Daemon::Control daemon is running.
by Anonymous Monk on Feb 06, 2015 at 21:26 UTC

    I haven't used Daemon::Control before, but it does indeed sound like do_status should be the right way to do it. The module does have quite a few open bugs - could this one be related to your issue? https://github.com/symkat/Daemon-Control/pull/68

    ... presumably because the executable is different.

    Not sure what you mean by this? Are you not using the PID file? It also sounds like the scan_name option might be relevant?

Re: Test if Daemon::Control daemon is running.
by Anonymous Monk on Feb 07, 2015 at 12:27 UTC

    The following (quick & dirty) works fine for me, when run from the same user account (note each of these actually starts with shebang and use warnings; use strict;):

    # -- prog.pl -- my $run = 1; $SIG{TERM} = sub { $run=0 }; while($run) { sleep 1; `touch /tmp/foo` } `rm -f /tmp/foo`; # -- daem.pl -- use Daemon::Control; exit Daemon::Control->new( name => 'foobar', program => '/tmp/prog.pl', pid_file => '/tmp/prog.pid', )->run; # -- app.pl -- use Daemon::Control; my $stat = Daemon::Control->new( name => 'foobar', program => '/tmp/prog.pl', pid_file => '/tmp/prog.pid', quiet => 1, )->do_status; print "Status: $stat\n";

    It does not work if I don't define the pid_file or if I run app.pl as a different user (apparently due to the bug referenced above). So maybe one of those two things are the cause for your trouble? If it still doesn't work for you, could you show some code to reproduce?

      Thanks, everyone! First, you are correct that running from another script does work fine; to my embarrassment, in my test I used a relative path with FindBin and was looking in the wrong directory for the pid file. This solution works.

      However, in the course of this, I picked through the Daemon::Control code, and I'm a bit underwhelmed. Well, useful is the (undocumented, but callable) pid_running method, which does the actual check, and is used by (e.g.) do_status. But this method's MO seems quite inadequate; its only test is to SIG0 the pid. This means that if your daemon crashed and a new process shows up using the same pid the daemon had, then, e.g., do_stop will blindly kill this process!

      There is an optional scan_name parameter which does a bit more checking. It does this by spawning a UNIX shell which runs ps to see if the process matches a regex; this seems rather roundabout and inefficient, as opposed to (say) reading /proc/####/cmdline or lstat'ing /proc/####/exe. Maybe it's more portable?

      In any case, it's unsettling that this extra test is not the default, so that running Daemon::Control in the usual way can be unsafe. I'd previously assumed it was much more robust than this. Beware.

Re: Test if Daemon::Control daemon is running.
by Anonymous Monk on Feb 07, 2015 at 01:26 UTC
    I don't think Daemon::Control lets you query the daemons like that. I believe you have to check the system environment to see if it's running, as you are. This works too:
    $running = `pgrep -x script.pl`;