MooseX::Daemonize and init.d
It only took me two weeks in the Iron Man competition to fail. That may actually be some kind of record. The last few weeks at $work have been pretty busy and I haven’t had the time or energy to work on blog posts. However, with YAPC::NA only a few days away and my excitement growing I decided to write up a quick post with a bit of fun I had messing with daemons.
In the past I’ve written my daemons as simple scripts. They worked reasonably well but after a couple years and even more rewrites I decided to see what CPAN had to offer. In particular I thought I’d take a look at a more moosey implementation. Turns out it’s super easy and includes all the things I needed to run it as a system service.
package MyDaemon; use Moose; use Try::Tiny; use namespace::autoclean; with qw(MooseX::Daemonize); after start => sub { my $self = shift; return unless $self->is_daemon(); while (1) { try { # Your daemon code here } } sleep(3600); } };
That’s it. The MooseX::Daemonize code handles pretty much everything you’d expect a daemon to do. Next, I wanted it to be integrated as a system service. For that I had to make it runnable using MooseX::Runnable.
package MyDaemon; use Moose; use Try::Tiny; use namespace::autoclean; with qw(MooseX::Daemonize MooseX::Runnable); sub run { my $self = shift; $self->start(); exit(0); } after start => sub { my $self = shift; return unless $self->is_daemon(); while (1) { try { # Your daemon code here } } sleep(3600); } };
Ok, simple enough. Now the module can be run as an application using the mx-run command. On to the final step, the init.d script.
PIDFILE=/var/run/mydaemon.pid COMMAND="mx-run -I/path/to/MyDaemon.pm" # Source function library . /etc/rc.d/init.d/functions start() { echo -n "Starting My Daemon: " if [ -f $PIDFILE ]; then PID=`cat $PIDFILE` echo my daemon already running: $PID exit 2; fi daemon $COMMAND echo } stop() { echo -n "Stopping My Daemon: " killproc mydaemon echo } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status mydaemon ;; *) echo "Usage: {start|stop|restart|status}" exit 1 esac exit 0
Now I can do service mydaemon start/stop/status/restart and the system manages the daemon for me. A simple chkconfig and it’s running at startup. Very nice.
Please be aware that I’m running CentOS 5.4 so your mileage may vary in regards to the init.d script.
Keep up the postiness, by the way. I don’t understand any of it, of course, but I like that you’re doing it.
This is strange. Why do you check pidfile in init script when MooseX::Daemonize should do this for you?
Any why do you call killproc when you should call $daemon->stop?
BTW, you might be interested in Ubic. It is a complete perl-based service manager and with it you wouldn’t need init script at all.
It could work nicely together with MooseX::Daemonize too, I think.
Thanks for the comment. The idea behind my post was to integrate Moose into my daemons while still being able to use service and chkconfig inside Linux.
For me to use $daemon in my init script then it would have to be written in perl. I hadn’t even considered trying that and I’m not sure it would work. Now I’m curious though so I may need to do some investigation. 🙂
Ubic looks interesting I’ll try to hit you up on IRC to discuss.