POE::Component::Daemon::Win32 - Run POE as a Windows NT/2000/XP service
use POE qw( Component::Daemon::Win32 ); # generic callback - all events call the same subroutine POE::Component::Daemon::Win32->spawn ( Callback => \&sub ); # state-specific callback POE::Component::Daemon::Win32->spawn ( Callback => { start_pending => \&sub1, stop_pending => \&sub2, stopped => \&sub3, ... } );
POE::Component::Daemon::Win32 enables POE scripts to run as services via the Win32::Daemon module by Dave Roth. Full event-based callbacks are available on service state changes.
The following parameters may be passed to the spawn() constructor:
Specifies which subroutines should be called for any given states. If a coderef is passed, all events will call that subroutine. Alternately, a hashref may be specified. In this case, the hashref should contain state names for keys and coderefs for values. See below for a list of valid state names.
This optional parameter specifies the alias by which the underlying session will be known. If omitted, the alias will be set to a default of 'win32daemon'.
This optional parameter sets the frequency (in seconds) of service polls. If omitted, polls will occur approximately once every second.
Whenever the Win32 service state changes, events are fired off to the user-defined callbacks. Valid callback names are specified below in the STATES section.
Callbacks can either be defined per-state or can be delegated en masse to a single subroutine.
# per-state callback sub service_start_pending { my $kernel = $_[KERNEL]; # do some sort of initialization here $kernel->yield ('next_state'); } # generic callback sub service_state { my ($kernel, $state, $message) = @_[KERNEL, ARG0, ARG1]; # service start pending if ($state == SERVICE_START_PENDING) { # do some sort of initialization here } $kernel->yield ('next_state'); }
The second argument $state contains a number corresponding to the current service state. The parameter $message contains any service messages such as a pending system shutdown.
$state
$message
If you choose the latter, non-state specific approach, you only need to create one subroutine. Within the callback just compare the provided state with a list of service state constants. Please see the CONSTANTS section below for a list of valid state constants.
When your script is ready to move on to the next service state, simply notify the kernel of your intent like so:
$kernel->yield ('next_state');
If you do not pass on a next_state message, your callback will be invoked every cycle until you are ready for the next state. This allows you to take care of potentially long-running operations safely.
next_state
Note, however, that one should not take too long to acknowledge a state change or the Service Control Manager (SCM) may deem your service unresponsive. If this happens it will be impossible to interact with the service short of forcefully terminating its process.
The following states are recognized for use in Callback:
Callback
The Service Control Manager (SCM) is not ready.
Next state: start_pending.
start_pending
The SCM expects us to run our startup procedure at this point.
Next state: running.
running
Normal operation. The service should spend the vast majority of its time in this state.
The SCM has informed the service it should pause operation. This is not to be confused with the stopped state.
Next state: paused.
paused
The service should not perform anything above and beyond SCM interaction during this state.
The service is coming out of the paused state and should resume normal operation.
The service should start winding down. Typically one would start closing open filehandles/connections/etc. and generally cleaning up at this point.
Next state: stopped
stopped
The service has stopped. After any callback has returned, no further service communications will take place. The component will then be destroyed.
The system on which the service is running has been instructed to shut down. This isn't really a state per se, but rather a message from the SCM.
If the service takes too long to stop, it runs the risk of being forcefully terminated by the SCM. By default, approximately 30 seconds are allowed for graceful service shutdown. If your service needs more time it should pass a delay, in milliseconds, with its next_state call.
# allow 45 seconds for service shutdown $kernel->yield ('next_state', 45 * 1000);
This state is provided to handle any states not specificially supported at this time.
The following service state constants are supported:
SERVICE_NOT_READY SERVICE_STOPPED SERVICE_RUNNING SERVICE_PAUSED SERVICE_START_PENDING SERVICE_STOP_PENDING SERVICE_CONTINUE_PENDING SERVICE_PAUSE_PENDING
The following service message constant is supported:
SERVICE_CONTROL_SHUTDOWN
For more information about each state and its purpose, please see Win32::Daemon.
Peter Guzis <pguzis@cpan.org>
Win32::Daemon
To install POE::Component::Daemon::Win32, copy and paste the appropriate command in to your terminal.
cpanm
cpanm POE::Component::Daemon::Win32
CPAN shell
perl -MCPAN -e shell install POE::Component::Daemon::Win32
For more information on module installation, please visit the detailed CPAN module installation guide.