Aug 16

Lately I’ve become a big fan of the Nginx + Starman combination for Perl-based web development. mod_perl has served me well for fifteen years, but with Plack/PSGI replacing the mod_perl API, it makes less sense to configure and install Apache just to invoke a PSGI handler. Starman has near-zero configuration, and Nginx provides a perfect complement for HTTP acceleration and serving static files.

To facilitate using these servers I added Nginx and Starman plugins for Server::Control, which previously existed mainly for Apache.

So what’s Server::Control?

Server::Control is a set of libraries for controlling servers, where a server is any background process which listens to a port and has a pid file. Think apachectl on steroids
(and not for just Apache).

In the happy case, controlling a pid-file server is simple – just run the command to start it, and run kill `cat /path/to/pidfile` to stop it. Where Server::Control comes in is handling all the little unhappy cases.

For example, accidentally starting a server that’s already running or stopping a server that isn’t:

    % bin/ -k start
    server 'mhq' is already running (pid 5912) and listening to port 5000

    % bin/ -k stop
    server 'mhq' is not running

or trying to start a server whose port being blocked by another process:

    % bin/ -k start
    cannot start server 'mhq' - pid file
    '/Users/swartz/git/mason-site.git/data/' does not exist,
    but something (possibly pid 5943 - "/usr/local/bin/plackup") is listening
    to localhost:5000

or a corrupt pid file, left over from a reboot or a kill -9:

    % bin/ -k start
    pid file '/Users/swartz/git/mason-site.git/data/' contains 
    a non-existing process id '5985'!
    deleting bogus pid file '/Users/swartz/git/mason-site.git/data/'

or a server that starts but isn’t listening to the expected port:

    % bin/ -k start
    waiting for server start
    after 10 secs, server 'mhq' appears to be running (pid 6167), but not
    listening to port 5000

or a server that starts but isn’t serving content correctly (using the validate_url and validate_regex parameters):

    % bin/ -k start
    waiting for server start
    server 'mhq' is now running (pid 6080) and listening to port 5000
    validating url 'http://localhost:5000/'
    content of 'http://localhost:5000/' (12798 bytes) did not match
    regex 'qr/(?-xism:Welcome to Mason and Poet)/'

So I always take the extra time to set up Server::Control, and it usually pays off in reduced frustration in the end. For convenience I have aliases like this set up to start, stop, restart and ping (check the status of) each server on a machine:

    alias ctlmhq='/home/swartz/servers/mhq/bin/ -k'
    alias stamhq='ctlmhq start'
    alias stomhq='ctlmhq stop'
    alias remhq='ctlmhq restart'
    alias pingmhq='ctlmhq ping'

2 Responses to “Controlling Nginx and Starman with Server::Control”

  1. Christiaan Kras Says:

    I’ve been using Daemon::Control for starting and stopping services written in Perl. It seems more generic than Server::Control, which seems to provide support for a couple of services. Though it does seem to be rather flexible if you need to implement specific behavior.

  2. Perl Weekly Issue #56 – August 20, 2012 – community and language | BerliOS Says:

    [...] Controlling Nginx and Starman with Server::Control [...]

Leave a Reply

preload preload preload