Hi,
Well, I am not sure if this is going to be the best solution long term, but
it works!
while ( <$connection> ){
my $return_value = undef;
if (/quit|exit/i) { last; }
elsif (/closeme/i ) {$connection->close(); }
elsif (/date|time/i) { printf $connection "%s\n", scalar
localtime; exit(0); }
that did call to a sub, and then connected to a database. I am wondering if
that connection object is better off being global. I changed the connect to
be global, restarted and did a test and it worked fine! I was all ready to
post back to here with the good news, when just to double check I went back
and made the db connect in the local sub like before. And it still worked?!
So it seems like I might be in better shape for now, but I might have some
long term problems with DB connections dieing, most likely related to this
child handling. I have to think that becase the query I am doing is VERY
well tested and never causes an issue.
Thanks tremedously for everyone's help so far, I at the very least have some
directions to go in now.
I still would very much like to learn what the correct, put it in the book
solution should be..
Eric
At 03:57 PM 9/16/03 +0100, Stephen Hardisty wrote:
>Hi,
>I had a problem with 5.8.1 and forking in that I was either getting zombies
using the 5.6 examples or the parent was dying, depending on which example
was used. The way round I found was to:
>
># ignore the child, good rule for life
>$SIG{CHLD} = 'IGNORE';
>
># then sort out the socket
>my $server = new IO::Socket::INET(LocalPort => $port,
> Type => SOCK_STREAM,
> Proto => "tcp",
> Listen => 5)
> or die "some error";
>
># wait for a connection
>while(my $client = $server->accept())
>{
> my $pid = fork;
> die "Error. Fork: $!\n" unless defined $pid;
>
> if($pid == 0)
> {
> # all your child code here
>
> # when it's done, kill the child:
> exit(0);
> }
>}
>
>This seemes reasonably stable. If anybody has a better way, then I'm all ears.
>
>Cheers!
>
>-----Original Message-----
>From: Eric Frazier [mailto:[EMAIL PROTECTED]
>Sent: 16 September 2003 12:24
>To: [EMAIL PROTECTED]
>Cc: [EMAIL PROTECTED]
>Subject: Re: mod_perl v2 Forking
>
>
>Hi,
>
>I guess this is off topic for this list, since I would be doing this no
>matter if I was running CGI or mod_perl or whatever. I am pretty desparate
>to get this working, and if anyone wants to earn some cash helping me fix
>things PLEASE call me at 250 655-9513.
>
>I have been trying to accomplish the same thing as Cameron, but with the
>detaching stuff it seemed a lot easier to make a server with IO::Select and
>not actually start the server from mod_perl. The end result hopefully will
>be a web user being able to start some things that take time, but not screw
>things up by interrupting them.
>
>But then I found I was using 5.8.. Thanks to a guy on comp.lang.perl.misc I
>know that there is a change in how signals are handled, they call it
>deferred signal handling because Perl now is suppose to wait until the
>Interpeter is in a safe state. As I understand it this might avoid some
>things like core dumps or other errors related to dieing while trying to do
>something besides dieing.
>
>The thing is somehow this ends up killing off my parent process, just like
>in this post:
>
>http://www.mail-archive.com/[EMAIL PROTECTED]/msg43989.html
>
>So this is happening to me as well, however the guy in the above example had
>his problem solved by using Errno and looking for EINTR if that error is
>raised then catch it and move on,
>
>I did get one maybe helpfull thing from my log:
>
>Erro was %! --------
>./franken_socket.pl 8607: got - CHLD
> at Tue Sep 16 02:17:42 2003
>I got forked
>./franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003
>begat 8607
>./franken_socket.pl 8599: got - CHLD
> at Tue Sep 16 02:17:54 2003
>./franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54 2003
>reaped 1Erro was No child processes %! --------
>
>So it looks like the parent got killed on that error "No child process"
>This code works just fine on 5.6 since it is about 150% from examples :)
>The above is the result of connecting, doing a "who", and doing "dienow" to
>test the alarm.
>
>I also found this:
>
>http://archive.develooper.com/[EMAIL PROTECTED]/msg03022.html
>
>Which totaly describes my problem as well, but shows it happening with perl
>5.8.1..
>
>
>>I'd imagine that your accept() isn't being restarted. How does it work
>>if you change the loop to look like this?
>
>> use Errno;
>
>> while (1) {
>> my $client = $server->accept or do {
>> next if $!{EINTR};
>> last;
>> };
>> spawn(\&function, "whatever");
>> }
>
>#!/usr/bin/perl -w
>
>## new frankenstein!
>
> use strict;
> use POSIX ();
> use POSIX 'WNOHANG';
> use Errno;
> use IO::Socket;
> use FindBin ();
> use File::Basename ();
> use File::Spec::Functions;
> use Net::hostent;
> use Carp;
>
>
> $|=1;
> my $pid;
>
>open (DIED, ">>/var/log/daemon_log") or warn "$!";
>sub logmsg { print DIED "$0 $$: @_ at ", scalar localtime, "\n" }
>
>my $listen_socket = IO::Socket::INET->new(LocalPort => 1081,
> LocalAddr => '127.0.0.1',
> Proto => 'tcp',
> Listen => SOMAXCONN,
> Reuse => 1 )
>or die "can make a tcp server on port 1080 $!";
>
>
> # make the daemon cross-platform, so exec always calls the script
> # itself with the right path, no matter how the script was invoked.
> my $script = File::Basename::basename($0);
> my $SELF = catfile $FindBin::Bin, $script;
> # POSIX unmasks the sigprocmask properly
> my $sigset = POSIX::SigSet->new();
> my $action = POSIX::SigAction->new('sigHUP_handler',
> $sigset,
> &POSIX::SA_NODEFER);
> my $action_alrm = POSIX::SigAction->new('sigALRM_handler',
> $sigset,
> &POSIX::SA_NODEFER);
>
>
> POSIX::sigaction(&POSIX::SIGHUP, $action);
> POSIX::sigaction(&POSIX::SIGALRM, $action_alrm);
>
> sub sigHUP_handler {
> print "got SIGHUP\n";
> exec($SELF, @ARGV) or die "Couldn't restart: $!\n";
> }
> sub sigALRM_handler {
> print "got ALARM timeout\n";
>
> }
>
> $SIG{CHLD} = \&REAPER_NEW;
>
> sub REAPER {
> $SIG{CHLD} = \&REAPER; # loathe sysV
> my $waitedpid = wait;
> logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
> }
>
> sub REAPER_NEW {
> logmsg "got - @_\n";
> my $wpid = undef;
> while ($wpid = waitpid(-1,WNOHANG)>0) {
>
> logmsg "main $pid -- reaped $wpid" . ($? ? " with exit $?"
: '')
>;
> print DIED "reaped $wpid" . ($? ? " with exit $?" : '');
>
> }
> }
>
>
> print "PID: $$\n";
> print "ARGV: @ARGV\n";
> print "[Server $0 accepting clients]\n";
>
>#while (my $connection = $listen_socket->accept()) {
>while (1) {
> my $connection = $listen_socket->accept() or do {
> next if $!{EINTR};
> last;
> };
>
> print DIED "Erro was $! %! --------\n";
>$connection->autoflush(1); ## missing seemed to cause client problem, but
>not telnet
>
> if (!defined($pid = fork)) {
> logmsg "cannot fork: $!";
>
> }elsif ($pid) {
> logmsg "begat $pid";
> print DIED "begat $pid\n";
> }else{
> # else i'm the child -- go spawn
> print $connection "Command?";
>
> while ( <$connection> ){
>
> my $return_value = undef;
>
> if (/quit|exit/i) { last; }
> elsif (/closeme/i ) {$connection->close(); }
> elsif (/date|time/i) { printf $connection "%s\n", scalar
>localtime; }
> elsif (/who/i ) { print $connection `who 2>&1`;}
> elsif (/dienow/i ) { alarm 2; }
> elsif (/dieT/i ) { die; }
>
>
>
> #REAPER_NEW($pid) if $return_value;
>
> print $connection "Command?";
>
> print DIED "I got forked\n";
>}
> exit(0);
>
> #STDIN->fdopen($connection,"r") || die "can't dup client to stdin";
> #STDOUT->fdopen($connection,"w") || die "can't dup client to
stdout"
>;
> #STDERR->fdopen($connection,"w") || die "can't dup stdout to
stderr";
>
> ### FORKed code here..
>
> } ## end while <$connection>
>
>} ## end else
>
>close ($listen_socket);
>
>
>
>
>At 01:18 AM 9/16/03 -0700, Stas Bekman wrote:
>>Cameron B. Prince wrote:
>>
>>> I have a report generator program written in Perl that I need to start from
>>> a CGI. The program takes about 15 minutes to run, so I must fork or double
>>> fork. I have two goals:
>
>(250) 655 - 9513 (PST Time Zone)
>
>"Inquiry is fatal to certainty." -- Will Durant
>
>
>
>
>
>________________________________________________________________________
>This email has been scanned for all viruses by the MessageLabs Email
>Security System. For more information on a proactive email security
>service working around the clock, around the globe, visit
>http://www.messagelabs.com
>________________________________________________________________________
>
>________________________________________________________________________
>This email has been scanned for all viruses by the MessageLabs Email
>Security System. For more information on a proactive email security
>service working around the clock, around the globe, visit
>http://www.messagelabs.com
>________________________________________________________________________
>
(250) 655 - 9513 (PST Time Zone)
"Inquiry is fatal to certainty." -- Will Durant