On Wed, Mar 21, 2001 at 11:09:13AM -0800, Rob Bloodgood wrote:
> In trying to make my app as long-lived and stable as possible, I've come up
> against a snag:
> In the even that my program fails, even when wrapped in an eval loop,
> when I try to re-start things, I find that there are existing sessions in
> memory, my previous incarnations of POE::Component::Server::TCP, which give
> me bind errors( # 98 in my linux system if UR interested). <sigh>
>
> It would be great if I could capture the session ID's somehow so that I
> could stop/deallocate/wait on them explicitly, before restarting.
The biggest problem here is that POE::Kernel wasn't designed to be
stopped and restarted. It may be easier to wrap the program in a
shell script that checks its return value and restarts it if there was
a problem.
> POE::Component::Server::TCP->new
> ( Port => 30003,
> Acceptor => sub {
> my ($socket, $peer_addr, $peer_port) = @_[ARG0, ARG1, ARG2];
> print "Server::TCP received a connection.\n" if DEBUG;
> # spawn the server session
> ServerSession->new($socket, $peer_addr, $peer_port);
> },
> Error => sub { # Optional.
> my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2];
> print "Server::TCP detected $operation error $errnum: $errstr\n"
> if $errnum;
> $::try++, die "\n" if $errnum == 98;
> },
> );
Maybe you don't need to die there. Here's an off-the-cuff
"meta-server" that respawns a server whenever it receives a
'new_server' event. The server, created within the 'new_server' event
handler, posts the meta-server a 'new_server' event whenever it dies
with error 98.
The one undocumented bit is that the TCP server component holds its
socketfactory wheel in $_[HEAP]->{listener}. You'll need to delete
that for the component to shut its listening socket down. Client::TCP
in POE 0.1207 or later will include a 'shutdown' event handler that
deletes $_[HEAP]->{listener} for you.
POE::Session->create
( inline_states =>
{ _start => sub {
$_[KERNEL]->alias_set( 'meta_server' );
$_[KERNEL]->yield( 'new_server' );
},
new_server => sub {
POE::Component::Server::TCP->new
( ...,
Error => sub {
my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2];
# Shut down the TCP server component.
if ($POE::VERSION < 0.1207) {
delete $_[HEAP]->{listener}; # undocumented
}
else {
$_[KERNEL]->yield( 'shutdown' ); # documented after 0.1206
}
# Start a new TCP server component. This probably
# should go last, since it allows the 'shutdown' event
# to be dispatched before 'new_server' starts a new
# server.
$_[KERNEL]->post( meta_server => 'new_server' )
if $errnum == 98;
},
);
},
}
);
I've also added an Alias parameter for Server::TCP so they can be shut
down from outside themselves. This will appear in 0.1207 or later.
>From the new documentation:
=item Alias
Alias is an optional name by which this server may be referenced.
It's used to pass events to a TCP server from other sessions.
Alias => 'chargen'
Later on, the 'chargen' service can be shut down with:
$kernel->post( chargen => 'shutdown' );
-- Rocco Caputo / [EMAIL PROTECTED] / poe.perl.org / poe.sourceforge.net