Skip Menu |

This queue is for tickets about the POE CPAN distribution.

Report information
The Basics
Id: 1682
Status: resolved
Priority: 0/
Queue: POE

People
Owner: RCAPUTO [...] cpan.org
Requestors: RCAPUTO [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: add Timeout to PoCo::Client::TCP
Client::TCP needs a timeout, so people don't need to code it themselves.
From: Casey Zacek <perl [...] bogleg.org>
[RCAPUTO - Wed Oct 16 16:02:50 2002]: Show quoted text
> Client::TCP needs a timeout, so people don't need to code it
themselves. Here's a patch with no documentation. :) Adds two parameters to new(): Timeout => 5 # seconds, default = old behavior (no timeout?) ConnectTimeout => coderef # handle called just like ConnectError, with ARG1,ARG2 set to $!+0 and $!, which are set to ETIMEDOUT (from POSIX.pm).
--- TCP.pm 2002-09-11 21:46:24.000000000 -0500 +++ /root/.cpan/build/POE-0.23/POE/Component/Client/TCP.pm 2002-10-16 17:11:33.000000000 -0500 @@ -8,6 +8,7 @@ $VERSION = (qw($Revision: 1.21 $ ))[1]; use Carp qw(carp croak); +use POSIX qw(ETIMEDOUT); # Explicit use to import the parameter constants; use POE::Session; @@ -45,9 +46,10 @@ my $domain = delete $param{Domain}; my $bind_address = delete $param{BindAddress}; my $bind_port = delete $param{BindPort}; + my $timeout = delete $param{Timeout}; foreach ( qw( Connected ConnectError Disconnected ServerInput - ServerError ServerFlushed + ServerError ServerFlushed ConnectTimeout ) ) { croak "$_ must be a coderef" @@ -56,6 +58,7 @@ my $conn_callback = delete $param{Connected}; my $conn_error_callback = delete $param{ConnectError}; + my $conn_to_callback = delete $param{ConnectTimeout}; my $disc_callback = delete $param{Disconnected}; my $input_callback = delete $param{ServerInput}; my $error_callback = delete $param{ServerError}; @@ -99,6 +102,7 @@ } $conn_error_callback = \&_default_error unless defined $conn_error_callback; + $conn_to_callback = \&_default_error unless defined $conn_to_callback; $error_callback = \&_default_io_error unless defined $error_callback; $disc_callback = sub {} unless defined $disc_callback; @@ -137,6 +141,10 @@ SuccessEvent => 'got_connect_success', FailureEvent => 'got_connect_error', ); + $_[KERNEL]->alarm_remove( delete $heap->{timeout_id} ) + if exists $heap->{timeout_id}; + $heap->{timeout_id} = $_[KERNEL]->alarm_set( + got_connect_timeout => time + $timeout ) if defined $timeout; }, connect => sub { @@ -149,6 +157,9 @@ got_connect_success => sub { my ($kernel, $heap, $socket) = @_[KERNEL, HEAP, ARG0]; + $kernel->alarm_remove( delete $heap->{timeout_id} ) + if exists $heap->{timeout_id}; + # Ok to overwrite like this as of 0.13. $_[HEAP]->{server} = POE::Wheel::ReadWrite->new ( Handle => $socket, @@ -165,11 +176,24 @@ got_connect_error => sub { my $heap = $_[HEAP]; + $_[KERNEL]->alarm_remove( delete $heap->{timeout_id} ) + if exists $heap->{timeout_id}; $heap->{connected} = 0; $conn_error_callback->(@_); delete $heap->{server}; }, + got_connect_timeout => sub { + my $heap = $_[HEAP]; + $heap->{connected} = 0; + $_[KERNEL]->alarm_remove( delete $heap->{timeout_id} ) + if exists $heap->{timeout_id}; + $! = ETIMEDOUT; + @_[ARG0,ARG1,ARG2] = ('connect', $!+0, $!); + $conn_to_callback->(@_); + delete $heap->{server}; + }, + got_server_error => sub { $error_callback->(@_); $_[KERNEL]->yield("shutdown") if $_[HEAP]->{shutdown_on_error};
[guest - Wed Oct 16 18:16:44 2002]: Show quoted text
> [RCAPUTO - Wed Oct 16 16:02:50 2002]: > > Here's a patch with no documentation. :) > > Adds two parameters to new():
Timeout => SECONDS, ConnectTimeout => CODEREF, I think it would be more expandable if we reused ConnectError for the timeout handler. We can force the error operator to be "connect" and the error number/message to be ETIMEDOUT. That lets us replace Timeout with ConnectTimeout, which opens the future possibility of InputTimeout. If it's ok with you, I'll modify the patch before applying it. -- Rocco Caputo / troc@pobox.com / poe.perl.org / poe.sf.net
From: Casey Zacek <perl [...] bogleg.org>
[RCAPUTO - Thu Oct 17 12:55:43 2002]: Show quoted text
> I think it would be more expandable if we reused ConnectError for > the timeout handler. We can force the error operator to be > "connect" and the error number/message to be ETIMEDOUT. > > That lets us replace Timeout with ConnectTimeout, which opens the > future possibility of InputTimeout.
Here's a new patch with that done (and even a little bit of documentation). I started to implement InputTimeout, but the problem is that we don't know when to start expecting input exactly. Casey Zacek <perl@bogleg.org>
--- TCP.pm 2002-09-11 21:46:24.000000000 -0500 +++ /root/.cpan/build/POE-0.23/POE/Component/Client/TCP.pm 2002-10-18 14:34:59.000000000 -0500 @@ -8,6 +8,7 @@ $VERSION = (qw($Revision: 1.21 $ ))[1]; use Carp qw(carp croak); +use POSIX qw(ETIMEDOUT); # Explicit use to import the parameter constants; use POE::Session; @@ -45,6 +46,7 @@ my $domain = delete $param{Domain}; my $bind_address = delete $param{BindAddress}; my $bind_port = delete $param{BindPort}; + my $ctimeout = delete $param{ConnectTimeout}; foreach ( qw( Connected ConnectError Disconnected ServerInput ServerError ServerFlushed @@ -137,6 +139,10 @@ SuccessEvent => 'got_connect_success', FailureEvent => 'got_connect_error', ); + $_[KERNEL]->alarm_remove( delete $heap->{ctimeout_id} ) + if exists $heap->{ctimeout_id}; + $heap->{ctimeout_id} = $_[KERNEL]->alarm_set( + got_connect_timeout => time + $ctimeout ) if defined $ctimeout; }, connect => sub { @@ -149,6 +155,9 @@ got_connect_success => sub { my ($kernel, $heap, $socket) = @_[KERNEL, HEAP, ARG0]; + $kernel->alarm_remove( delete $heap->{ctimeout_id} ) + if exists $heap->{ctimeout_id}; + # Ok to overwrite like this as of 0.13. $_[HEAP]->{server} = POE::Wheel::ReadWrite->new ( Handle => $socket, @@ -165,11 +174,24 @@ got_connect_error => sub { my $heap = $_[HEAP]; + $_[KERNEL]->alarm_remove( delete $heap->{ctimeout_id} ) + if exists $heap->{ctimeout_id}; $heap->{connected} = 0; $conn_error_callback->(@_); delete $heap->{server}; }, + got_connect_timeout => sub { + my $heap = $_[HEAP]; + $heap->{connected} = 0; + $_[KERNEL]->alarm_remove( delete $heap->{ctimeout_id} ) + if exists $heap->{ctimeout_id}; + $! = ETIMEDOUT; + @_[ARG0,ARG1,ARG2] = ('connect', $!+0, $!); + $conn_error_callback->(@_); + delete $heap->{server}; + }, + got_server_error => sub { $error_callback->(@_); $_[KERNEL]->yield("shutdown") if $_[HEAP]->{shutdown_on_error}; @@ -191,6 +213,8 @@ my $heap = $_[HEAP]; $heap->{shutdown} = 1; + $_[KERNEL]->alarm_remove( delete $heap->{ctimeout_id} ) + if exists $heap->{ctimeout_id}; if ($heap->{connected}) { if (defined $heap->{server}) { delete $heap->{server} @@ -256,25 +280,26 @@ # Complete usage. POE::Component::Client::TCP->new - ( RemoteAddress => "127.0.0.1", - RemotePort => "chargen", - BindAddress => "127.0.0.1", - BindPort => 8192, - Domain => AF_INET, # Optional. - - Connected => \&handle_connect, - ConnectError => \&handle_connect_error, - Disconnected => \&handle_disconnect, - - ServerInput => \&handle_server_input, - ServerError => \&handle_server_error, - ServerFlushed => \&handle_server_flush, - - Filter => "POE::Filter::Something", - - InlineStates => { ... }, - PackageStates => [ ... ], - ObjectStates => [ ... ], + ( RemoteAddress => "127.0.0.1", + RemotePort => "chargen", + BindAddress => "127.0.0.1", + BindPort => 8192, + Domain => AF_INET, # Optional. + ConnectTimeout => 5, # Seconds; optional. + + Connected => \&handle_connect, + ConnectError => \&handle_connect_error, + Disconnected => \&handle_disconnect, + + ServerInput => \&handle_server_input, + ServerError => \&handle_server_error, + ServerFlushed => \&handle_server_flush, + + Filter => "POE::Filter::Something", + + InlineStates => { ... }, + PackageStates => [ ... ], + ObjectStates => [ ... ], ); # Sample callbacks.
Applied. Thank you. I also documented the new parameter some more and made some minor whitespace changes to the code. -- Rocco Caputo / troc@pobox.com / poe.perl.org / poe.sf.net