jhanna has asked for the wisdom of the Perl Monks concerning the following question:

I've got a totally cool bayesian spam filter smtp proxy, but it dies mysteriously after a few hours in win2k with ActivePerl. I've posted the main loop below -- if you have insight how to fix it I'd love to know.

On the other hand, is there a good Net::Server replacement for Active perl? I think the reason it dies is that running an internet server in perl in win2k is touchy... I've thought about rewriting for fork instead of select, but I wasn't sure it would solve the problem, and it'd be some work.

Thanks,
John

use IO::Select; use IO::Socket; $lsn = new IO::Socket::INET(Listen => 10, LocalPort => $listenPort); #print "l=$lsn\n"; $sel = new IO::Select( $lsn ); $nextNoop=time; $endtime=$nextNoop+$RestartEvery; $saveWhite=$nextNoop+$UpdateWhitelist; $noops2=$noops>>1+1; mlog(0,"Starting"); $SIG{INT}=sub {mlog(0,'Sig INT'); &SaveWhitelist; kill 6,$$;}; while(1) { @ready = $sel->can_read($noops2); foreach $fh (@ready) { if($fh == $lsn) { # Create a new socket my $client=$lsn->accept; my $server=new IO::Socket::INET(Proto=>'tcp',PeerAddr=>$smtpDestina +tion); addfh($client,\&getline,$server); addfh($server,\&reply,$client); my $ip=$Con{$client}->{ip}=$client->peerhost(); if($ip=~/^($acceptAllMail)/io) { $Con{$client}->{relayok}=1; } $time=gmtime(); $time=~s/... (...) (..) (........) ..(..)/$2 $1 $4 +$3/; $Con{$client}->{header}="Received: from $ip ($ip) by $me ; $time -0 +000\n"; } else { $buf=''; if($fh->sysread($buf,10240)>0) { $this=$Con{$fh}; $buf=$this->{_}.$buf; while($buf=~/(.*\n)/g) { ${$Con{$fh}}{getline}($fh,$1); } ($this->{_})=$buf=~/([^\n\r]*)$/s; } else { done($fh); } } } $time=time; if($time >= $nextNoop) { # boring code ommitted :-) } $ltime=$time; } # Never reached... # done with a file handle -- close him and his friend sub done { my $fh=shift; done2($Con{$fh}->{friend}); done2($fh); } # close a file handle & clean up associated records sub done2 { my $fh=shift; return unless $fh; my $this=$Con{$fh}; return unless $this; #print "closing $fh\n"; # remove timers for the filehandle delete $NoopList{$fh}; delete $NoopListTime{$fh}; # close the maillog if it's still open my $f=$this->{maillogfh}; close $f if $f; # remove from the select structure $sel->remove($fh); # close it $fh->close; # delete the Connection data delete $Con{$fh}; } # adding a socket to the Select structure and Con hash sub addfh { my ($fh,$getline,$friend) =@_; $sel->add($fh); binmode($fh); $Con{$fh}={}; my $this=$Con{$fh}; $this->{getline}=$getline; $this->{friend}=$friend; #print "add $fh: f=$friend\n"; }

Replies are listed 'Best First'.
Re: Net::Server for ActivePerl?
by hiseldl (Priest) on Dec 05, 2002 at 20:40 UTC

    Take a look at the networking code from "Advanced Perl Programming" (here is the example code directory). In particular look in the Networking directory for Msg.pm, the server code is toward the bottom. You can look at the code and get some ideas or you may be able to subclass Msg.pm to meet your needs. The RPC.pm class is an example of subclassing the Msg.pm class.

    --
    hiseldl
    What time is it? It's Camel Time!

      The O'Reilly book is interesting, and their code is nice, but this has nothing to do with my question.

      I'm looking for Net::Server{::Fork|::Multiplex|::PreFork} type behavior that works in Windows 2000 with ActivePerl 5.6.1. I know how to make a socket thank you. :-)

      john

        Sorry. I was trying to help as asked by the first part of your post.

          it dies mysteriously after a few hours in win2k ... if you have insight how to fix it I'd love to know.

        The demo code server seems to run pretty well and may stay alive longer.

        :-)

        --
        hiseldl
        What time is it? It's Camel Time!

      Ok... I take that back... Msg.pm might work.

      j

Re: Net::Server for ActivePerl?
by hiseldl (Priest) on Dec 05, 2002 at 20:13 UTC
      I looked at win32 daemon -- it's a good thing and is a substantial improvement over servany, but it doesn't help the socket server problem.

      J

Re: Net::Server for ActivePerl?
by bbfu (Curate) on Mar 13, 2003 at 00:09 UTC

    Several months too late, but I just found this node... :/

    I was able to get Net::Server to work under ActiveState Perl. I had to install via the cpan shell and force the install, as several of the tests rely on alarm, which isn't implemented in ActivePerl. Once I forced the install, though, the module itself seemed to work fine. I must admit, however, that I haven't tested it extensively and there may be some bugs I just haven't run into.

    I'd be interested to know if anyone has used Net::Server on ActivePerl and if there are any issues to be aware of. I sent an email to the author but haven't received a response yet.

    P.S.  I'm curious to know how exactly the code "dies mysteriously" and whether or not you got this issue resolved. I wrote a small custom POP3 server that I'm running on Win2k and it seems to stop accepting new connections after some fairly large number of hours. (Maybe between 12 and 24? I'm not sure exactly.) It only handles a single connection at a time, though, and the process remains, so it seems more like it's not closing its active connection properly. I haven't done much testing yet but was curious if this might be related. *shrug*

    bbfu
    Black flowers blossum
    Fearless on my breath