The standard method is to send the script a SIG HUP (Hang UP) which you catch with a signal handler and do the reininitialization you need. Here is an example I use:

BEGIN { # allow script to be reinitialized with a HUP signal $SIG{HUP} = sub { $HUP = 1; warn "Caught HUP\n" }; } # main loop while ( 1 ) { $conn = accept_new_conn(); # check if we have been HUPPED if ( $HUP ) { REHUP: # reset the flag $HUP = 0; warn "***** Widget reinitializing\n"; do_disconnect(); do_init(); # now it is possible, but unlikely that we get another SIG HUP + while # we are performing our reinit routines so we need to redo thi +s # stuff if that occurs, otherwise we will be partially reiniti +alised goto REHUP if $HUP; } # more code here }

In this case I just set a var called $HUP. This is because I have multiple children that get this signal. They are not all active at the one time and all I need them to do is re-read data out of the database. To save useless database hits from children that are sitting inactive waiting for connections I have them check if they have been hupped in their main loop. That way you can send 100 HUPs but if only one child is currently active there will only be one call to the DB, rather than 100 x NUM_KIDS. If a child is active it will perform the required RE_INIT before it completes handling the client connection.

Note to send a HUP your HUPper will need to be root. In CGIs I handle this by adding this line to /etc/sudoers

apache ALL=NOPASSWD:/home/www/utility/sendHUP.pl

This lets me call the sendHUP.pl script via a system call in a CGI and have the required HUP happen without getting involved with suid scripts and all the security issues they entail.

The sendHUP.pl script forks due mostly to historical reasons as we did have a 2 second delay between HUPping each kid (so they would not all be rininitializing at once) but the delayed HUP as required technique now makes this unnecessary.

#!/usr/bin/perl -w # sendHUP.pl # this script need to be run as root, to do this we add an entry to # /etc/sudoers so that apache can run it (you edit using visudo) # visudo -f /etc/sudoers # add this line # apache ALL=NOPASSWD:/devel/www/utility/sendHUP.pl # call as system('sudo', '/devel/www/utility/sendHUP.pl'); $|++; #use strict; use Fcntl; use POSIX qw(setsid); # we really really don't want to half HUP the widgets # this can potentially occur so we ignore INT and TERM SIGs BEGIN { $SIG{INT} = $SIG{TERM} = sub { warn $SIG{INT} ? "*****sendHUP +caught INT" : "*****sendHUP caught TERM" } } my $PROGRAM = 'widget.pl'; my @ps = `ps -C $PROGRAM`; @ps = map { m/(\d+)/; $1 } grep { /\Q$PROGRAM\E/ } @ps; # now demonize it defined(my $pid = fork) or die "Can't fork: $!"; exit 0 if $pid; chdir '/' or die "Can't chdir to /: $!"; umask 0; setsid() or die "Can't start a new session: $!"; for ( @ps ) { (kill HUP, $_) or warn "***** Failed to HUP $_\n"; } my $time = gmtime(); warn "[$time] Sent SIGHUP to $PROGRAM @ps\n"; exit 0;

cheers

tachyon


In reply to Re: Restarting a script without dropping clients by tachyon
in thread Restarting a script without dropping clients by Ahbeyra

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.