Writing a simple server


[ Site Index] [ Attic Index] [ Perl Index] [ Feedback ]


If you run a Unix or Linux box, odds are you are used to the idea that there are various programs that you want to keep running -- all the time. Usually the Unix system itself can be trusted to keep programs running; there are various mechanisms to do this:

rc files
rc (originally runcom) files are shell scripts executed by the init(8) system when it switches "run levels". A Unix system that's turned off is in run level 0; run level 1 is single user mode (when the sysadmin is sitting at the console, cursing and trying to fix filesystems), run level 2 is standard multi-user mode, run level 3 is multi-user and NFS file-serving mode, and so on. When init(8) switches run levels, it runs rc scripts to switch some daemons off and turn others on. (At least, that's what happens if you're using a SYSV-type init system; BSD is a little different.)
cron jobs
cron is the system timed execution daemon; every minute it rummages through its configuration files, looking for programs which it has been told to execute on a regular basis.
at jobs
Another timed execute system: the atrun(8) daemon runs programs in it's queue that are scheduled for one-off or irregular execution.
inetd servers
inetd(8) waits for incoming TCP/IP connections on a variety of sockets; when one arrives, it forks an appropriate child process to handle the connection (so that incoming SMTP traffic is handled by a mail daemon, incoming HTTP requests are fielded by a web server, and so on -- note that in practice these protocols are usually handled by standalone programs, but we won't get into that here!).

This is a bit bewildering at first, and can make running a Unix box a real headache -- what processes are started by what? It gets even worse when you write your own processes that need to be executed on a constant basis, and restarted under some circumstances. And (with the arguable exception of inetd, which only handles TCP/IP servers) there's no provision for a server to keep processes running constantly, restarting them whenever they die. This isn't often required, but can come in useful when, for example, you want a process to run continuously; for example, a program to watch for filesystems becoming full and beep the console.

Here's a simple server I wrote. It's a basic Perl module that is intended to run multiple programs, restarting them whenever they die. The way it works is to run in a loop. When it enters the loop, it forks and execs one child for each entry in its list of programs to run. Before it gets into the loop, it creates a handler for the SIGCHLD signal; when a SIGCHLD is received (indicating the death of a child process) the handler works out which child died and fires up another copy of the program.

(This is very much a trivial spin-off of a work-in-progress, which involves the creation of a non-blocking object-oriented perl object server -- don't ask! I'm putting it here because it seems to be very generic and may be of use in some specialised situations.)

Example server
Server.pm module
Example client
Example client
hydra-0.1.tar.gz

(Note that this module has not been run through MakeMaker and turned into a distributable package; to install it, just drop Server.pm into a directory in your @INC path and delete the 'use lib "modules";' line from the example.)

Here's a brief description:

Synopsis
Given a list of programs (in @MAIN::spawn_list), start them all up and keeps them running until told to take them down.
Behaviour
  • If it receives a SIGTERM or SIGINT it kills its children.
  • If it receives a SIGHUP it kills and restarts them.
  • If it receives a SIGCHLD, it identifies the dead child and restarts it
If a coderef to a function is supplied to run(), it will be executed before quitting the SIGTERM or SIGINT handlers.
Example
  my $server = new Server;
  $server->register("/usr/bin/program.1");
  $server->register("/usr/bin/program.2");
  my ($exit_func) = sub { print "Quitting via SIGTERM or SIGINT\n"; }
  $server->run($exit_func);


[ Site Index] [ Attic Index] [ Perl Index] [ Feedback ]