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 




Reply via email to