Skip to content
June 18, 2010 / Andy

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.

3 Comments

Leave a Comment
  1. Alex Gorman / Jul 7 2010 7:47 PM

    Keep up the postiness, by the way. I don’t understand any of it, of course, but I like that you’re doing it.

  2. Vyacheslav Matyukhin / Sep 2 2010 1:34 PM

    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.

    • Andy / Sep 2 2010 3:05 PM

      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.

Leave a comment