On Friday, Sep 12, 2003, at 00:47 US/Pacific, [EMAIL PROTECTED] wrote:


Sergey,

ah, I see, you are new to the Ungainly Art, of not
only programming, which you are doing well in, but
the more Arcane art of Daemonology. So bear with me
while I try to write some 'back and fill' here.

A part of the problem is that many people see this
same basic 'design pattern' -

        if I had a server that could do foo
        then all I need to do is test that it is up...

[..]

Here is my 'grown up' server.cgi:


[..]

basically a good piece of code. The problem seems to

        a. how to check that the server is running
        b. how to get the server to run as a daemon
        c. how to tie those two together.
        d. once started how does one stop the server?

you basic strategy so far is to try to use
a pid file - which is mostly ok-ish, but has
the problem

        what if the pid file exists,
                and has a PID in it, Does that
                prove that the PID is
                        a. still alive
                        b. still our server

This is a classic 'oopsie' almost everyone makes.
They presume that since they can read the PID file
and it is some positive integer, that clearly the
Daemon is alive. What one needs is a
process grovelor - that will check the process table
and see what comes back.

my $line = `ps -p $pid`

eg:
[jeeves: 7:] perl -e 'my $pid = 665; my $server='WebServer'; my $line = `ps -p $pid` ; print "OK\n" if $line =~/$server/g; '
OK
[jeeves: 8:]


there really is a mini-web-server running on jeeves as pid 665:
[jeeves: 3:] ps -p 665
  PID  TT  STAT      TIME COMMAND
  665  p3  S+     0:01.47 perl -w ./WebServer.plx
[jeeves: 4:]

The second test is to change the $pid value and notice that
it will not work that way:
[jeeves: 8:] perl -e 'my $pid = 660; my $server='WebServer'; my $line = `ps -p $pid` ; print "OK\n" if $line =~/$server/g; '
[jeeves: 9:] ps -p 660
PID TT STAT TIME COMMAND
660 p3 S 0:00.06 -csh (csh)
[jeeves: 10:]


I take you on this side because of the fact that the PID_FILE
may have once held a server's pid 660 - but that PID has
been reallocated to a new process....

So at best the 'pid file' gambit is a STARTING PLACE! But know what
the limits are.

The second problem is 'detaching your server from the caller'
which is the fun of actually daemonizing a process. The first
trick is to create your server as a Daemon - which means that
it will need to

        a. close STDIN,STDOUT,STDERR
        b. detach itself from the controlling TTY.

there is the Proc::Daemon project at the CPAN
<http://search.cpan.org/author/EHOOD/Proc-Daemon-0.03/Daemon.pm>
which will help with this part.

A quick lesson on 'init scripting'. Most system daemons,
and this includes the web server, are started at boot
time with a simple 'init script' of the form

#!/bin/sh

        case "$1" in
                start) <the_daemon> <start_args>
                        ;;
                stop) <the_daemon> <stop_args>
                        ;;
        esac

So when building a daemon it is useful to think in
similar terms - this of course normally means having
a command line option pair
        '-b' : boot|begin
        '-k' : kill|klose

hence 'daemon -b' will start the daemon, and if it
already knows where the pid file is going to be, it
will then check to see if another daemon of it's type
is running, and either defer to the existing one, or
tell it to die, and take over.

the '-k' option will likewise check for the existence
of the pid file and signal the daemon to shutdown....

cf:
<http://www.wetware.com/drieux/pbl/Sys/daemon1.txt>

At which point one crawls back up to the basic question

So I need a piece of CGI code that will start the daemon?

If one put most of the basic common stuff in a perl library,
then you could have say

        sub server_running {
                #my $obj = shift; # if we plan to OO this
                my ($pid, $server) = @_;
                my $line = `ps -p $pid` ;
                return( ($line =~/$server/g) ? 1:0 );
        }

Since the 'daemon will detach itself' you can just
call it directly or call your intermediary 'init script'

        unless ( server_running($pid,$daemon) )
        {
                # your script will block here for the time
                # that it takes to fork out the daemon
                my $answer = `start_daemon start`;
                #
                # handle any 'wrong $answer' responses
                #
        }
        #
        # now you need to deal with what to do with the initial request
        # that needed to talk with the server
        #

At which point you have the other sets of problems about
how to get it to stop.... do you want it to listen on
an additional port for control messages that are out
of band of the usual 'user message traffic flow'....

HTH....

ciao
drieux

---


-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to