NAME

Net::muxDaemon -- a generic framework for network daemons.


SYNOPSIS

  use Net::muxDaemon;
  sub my_cmdprocessor {
    return $_[1]."\n";
  }
  new Net::muxDaemon(PROCESS_COMMAND => \&my_cmdprocessor);
  die "Huh? Net::muxDaemons aren't supposed to return!\n$!\n";


DESCRIPTION

Net::muxDaemon implements all the boring, nasty details that go into making a network daemon. It implements everything about a simple message-response server except the processing of messages into responses. This functionality, the guts of the server, is implemented by the user in a function.

The gist of Net::muxDaemon' usage is simple. See SYNOPSIS for all the code you would need to implement an echo server. The user's function will run as a Net::muxDaemon method. It will have all the power of any of other method with none of the worries.

Note that Net::muxDaemon is really only good for command processing, almost RPC-like functionality. The same client can't have more the one message being processed at a time without running some serious risks. (Actually, the same client could, but not on the same socket.) These risks can be avoided by designing the protocol around certain limitations; however, save yourself headaches and stress by making sure all clients wait for responses after each command.


EXPORTS

The syslog function and $KILLED are exported by default. To export $LOGTAG and $LOGFACILITY, use the :syslog export tag.

syslog($priority, $format, @args)
See the Sys::Syslog manpage. This function does not log anything unless $Net::muxDaemon::LOGTAG is set to something. This Net::muxDaemon global is exported, so you can do $LOGTAG = 'myLogLine'; anytime after useing Net::muxDaemon to start logging. Alternatively, if you can wait to start syslogging (as is typical if until you launch the Net::muxDaemon you can likely log to STDERR) you can pass Net::muxDaemon the LOGTAG option.

Basically, just call it all over the place. Then, if you want to log, pass Net::muxDaemon a LOGTAG option. Turn logging off from the command_processor by doing undef($LOGTAG). Turn logging back on by setting $LOGTAG to something.

Note that if you just want to change your syslog tag, changing $LOGTAG is not enough. Do this:

  undef $LOGTAG; 
  syslog(); 
  $LOGTAG = 'newtag';

$LOGTAG
When this is undef, syslog does nothing, otherwise it becomes the tag used in loglines. May be initialized by the LOGTAG option. See OPTIONS.

$LOGFACILITY
The syslog facility used for logging. May be initialized by the LOGFACILITY option. See OPTIONS. Defaults to 'daemon', but you can set it to any valid value before you start logging. To change it after having logged, do this:
  my($olt) = $LOGTAG; 
  undef $LOGTAG; 
  syslog(); 
  $LOGFACILITY = 'newfacility'; 
  $LOGTAG = $olt;

$KILLED
Make this true and the Net::muxDaemon will exit nicely after the current round of message processing.


CONSTRUCTOR

new ( [Hash-o-options] )
Creates a Net::muxDaemon. Options are passed by name. Never returns.


ATTRIBUTES

$this->{OPTION}
Options are stored in the hash, and changing some of them has no effect after the object initializes. Some options, however, are safe to change and begin effecting behavior immediately after any changes. The initialize-only options will be marked below. PROCESS_COMMAND is NOT an initialize-only option. If you set $this->{PROCESS_COMMAND}, the new setting will be in effect immediately. Of course, the current function will run until it exits as usual.

$this->{inbuffer}, $this->{outbuffer}, $this->{ready}, $this->{close}
These are for internal use. See getmore and getreq for a use for $this->{inbuffer}. The others could conceivably be useful, but these won't be documented except by the code that uses them.


OPTIONS

PROCESS_COMMAND
Code reference. If this option is undefined Net::muxDaemon will look for a sub named 'process_command', first in the caller's namespace, then in the Net::muxDaemon namespace. This might be useful if you want your routine to live in Net::muxDaemon's namespace, but the benefits of this are obscure. The arguments to this function will be ($this,$request,$client), where:
    $this
A reference to our own Net::muxDaemon object. This is where the command processing routine gets access to static information. See ATTRIBUTES for a list of useful attributes.

    $request
A scalar, containing the message read from the client.

    $client
A socket connected to the client. It is not necessary to send replies to the client directly. This should be useful, for example, when more complex communication needs to happen than a simple message-response.

The sub should return a string response to be sent back to the client. If undef, nothing will be written to the socket. Alternatively, it could return a hashref to tune the response. Right now, the following keys are recognized:
    reply
The reply string.

    CLOSE
If this is set, the socket will be closed after the reply is sent.

Because perl's anonymous subroutines act as closures with respect to lexical variables, you could conceivably use them to create your own static workspace for your command processor. Because Net::muxDaemon provides you with everything you should need (Ha!), this is is left as an exercise for the reader.

BASEDIR
Working directory - defaults to ($ENV{'PWD'} || "/tmp"). This is an initialize-only option.

LOGTAG
Prepended to all log lines - logging is off unless set. This is an initialize-only option. See the $LOGTAG export above.

LOGFACILITY
Which facility to log to - defaults to ``daemon''. This is an initialize-only option. See the $LOGFACILITY export above.

PASSWD --NOT USED--
The admin password - defaults to ``abc123''

INITHOOK
If set, and is a CODE ref, the referenced sub will be run just before listening for clients.

DIEHOOK
If set, and is a CODE ref, the referenced sub will be run at exit.

HOOKSUB
If set, and is a CODE ref, the referenced sub will be run every HOOKINT seconds.

HOOKINT
The interval at which the subroutine referenced by the HOOKSUB option is run - defaults to 120.

TIMEOUT
Timeout in seconds for various operations - defaults to 3.

EOC
Command separator or command length. If this attribute is numeric, it will determine the length of commands. Commands will be passed to the PROCESS_COMMAND routine in chunks of EOC length. Otherwise it will determine the end-of-command string. (Actually, it's an end-of-command regex.) Defaults to ``\n''.

GROUPNAME
Which group to run as - defaults to current gid. Initialize-only.

PORT
Which port to run on - defaults to 4321. Initialize-only.

HOST
Which host to listen on - defaults to '*'. Initialize-only.

PIDFILE
This file contains the process id - defaults to ``NetDaemon.pid''. BASEDIR will be prepended unless ``/'' is the first character. Initialize-only. Do not attempt to set this option from the command processing function!

POOL
An arryref to a hash of hosts. Unless you want to cluster your Net::muxDaemon, just use HOST and PORT. Takes the form of:
 POOL => [ { host => "hostname1",
             addr => "1.1.1.1:1234",
             sync_to => 10
           },
           { host => "hostname2",
             port => 1235,
             addr => "1.1.1.2",
             sync_to => 10
           }
         ]

The contents of {addr} will overwrite those of {host} (and {port}, if that part of {addr} is supplied.) For Net::muxDaemon, only {host}, {addr}, and {port} are used, and only those of the first locally bindable spec. However, these keys of the hashes in the aryref are the same as the Tie::CacheHash option {sync} (See the Tie::CacheHash manpage), so you may just want to fill it in so you can send it to both modules.

POOL overrides the PORT and HOST options, if present. At least one of the host specs must be bindable-to. This allows you to specify more than one server on the same machine. The servers will use Tie::CacheHash syncing to keep each other up to date with local changes. Tie::CacheHash syncs on the udp port specified, while Net::muxDaemon listens on the tcp port of the same number.


METHODS

These methods are not likely to be called except from the command processing function.

getmore(socket, bytecount, ref_to_scalar)
Retrieves bytecount bytes from socket and places them in the scalar referenced by ref_to_scalar.

getreq(socket, ref_to_scalar)
Retrieves a request from socket and places it in the scalar referenced by ref_to_scalar. The request will not be sent to the command processor after this. (Unless it is pushed into the %ready attribute manually by the caller.)