IO::So...Timeout(3pm)
π IO::Socket::Timeout β the manual, but make it cute π
okay so bestie, you know how IO::Socket is that Perl module that lets you open sockets? yeah. this is the glow-up. it's the IO::Socket::Timeout page from the Perl docs (perl v5.36.0, and the page itself is dated 2022-11-19, iykyk) and we're gonna go through every single thing on it together. grab a snack. π
β¨ NAME β¨
IO::Socket::Timeout β it's IO::Socket, but with read/write timeout. that's it, that's the whole vibe. π
πΈ VERSION πΈ
version 0.32. periodt.
π SYNOPSIS π
here's the whole thing in action, no cap:
use IO::Socket::Timeout;
# creates a standard IO::Socket::INET object, with a connection timeout
my $socket = IO::Socket::INET->new( Timeout => 2 );
# enable read and write timeouts on the socket
IO::Socket::Timeout->enable_timeouts_on($socket);
# setup the timeouts
$socket->read_timeout(0.5);
$socket->write_timeout(0.5);
# When using the socket:
use Errno qw(ETIMEDOUT EWOULDBLOCK);
print $socket "some request";
my $response = <$socket>;
if (! $response && ( 0+$! == ETIMEDOUT || 0+$! == EWOULDBLOCK )) {
die "timeout reading on the socket";
}
so like β make the socket, turn the timeouts ON, set them, then actually use it and check your errors. the 0+$! thing is you forcing that errno into a number, because vibes. π
π¦ DESCRIPTION π¦
okay so here's the tea. IO::Socket does let you set a timeout, bestie β but it's only for the connection. not for reading. not for writing. just the connect. that's it. π«
this module is the fix. it gives you a way to set a timeout on read / write operations on an IO::Socket instance β or honestly any IO::Socket::* module out there, like IO::Socket::INET. literally any of them. slay. π
π CLASS METHOD π
π« enable_timeouts_on π«
IO::Socket::Timeout->enable_timeouts_on($socket);
you hand it a socket, and it hands it right back to you β but now read and write timeouts are switched on for it. β¨ note that you still gotta use read_timeout and write_timeout on it afterwards to actually, y'know, set them. enabling β setting, bestie, don't get it twisted.
it returns the socket, so you can chain this method with other methods like the main character you are. π
and if the argument is undef? it just returns an empty list. no drama, no crash, we love a graceful exit. π
π METHODS π
heads up: all of these get called on a socket that has already been passed to enable_timeouts_on(). you can't skip that step, bestie, it's the prerequisite. π
π§ read_timeout
my $current_timeout = $socket->read_timeout();
$socket->read_timeout($new_timeout);
get or set the read timeout value, for a socket created with this module. that's the whole thing. π
π§ write_timeout
my $current_timeout = $socket->write_timeout();
$socket->write_timeout($new_timeout);
get or set the write timeout value, for a socket created with this module. twin of the one above, but for writing. πΈ
π§ disable_timeout
$socket->disable_timeout;
turns the read and write timeouts off for a socket created with this module. bye timeouts. π
π§ enable_timeout
$socket->enable_timeout;
re-enables the read and write timeouts for a socket created with this module. she's back. π₯
π§ timeout_enabled
my $is_timeout_enabled = $socket->timeout_enabled();
$socket->timeout_enabled(0);
get or set the fact of whether a socket has timeouts enabled. like, the boolean truth of it. β
π WHEN TIMEOUT IS HIT π
when a timeout hits β read or write β the function that was trying to do its little thing will return undef or an empty string, and $! gets set to ETIMEOUT or EWOULDBLOCK. you should test for both. no picking favorites. π
and yeah, you can import ETIMEOUT and EWOULDBLOCK by using POSIX:
use Errno qw(ETIMEDOUT EWOULDBLOCK);
bestie this is important: if you only check one of the two errno values, you're gonna have a bad time. check both. always. π¨
π IF YOU NEED TO RETRY π
wanna build a try / wait / retry situation? my honest recommendation is to use a third-party module for it, like Action::Retry. something like this:
my $socket;
my $action = Action::Retry->new(
attempt_code => sub {
# (re-)create the socket if needed
if (! $socket) {
$socket = IO::Socket->new(...);
IO::Socket::Timeout->enable_timeouts_on($socket);
$socket->read_timeout(0.5);
}
# send the request, read the answer
$socket->print($_[0]);
defined(my $answer = $socket->getline)
or $socket = undef, die $!;
$answer;
},
on_failure_code => sub { die 'aborting, to many retries' },
);
my $reply = $action->run('GET mykey');
see how it re-creates the socket if it needs to, sends the request, reads the answer, and bails with die $! if it got nothing back? that's the pattern. π«Ά
π IMPORT options π
you can pass a list of socket module names when you use this module β that way, internally, the composed classes that are needed get created and loaded at compile time. like:
use IO::Socket::Timeout qw(IO::Socket::INET);
efficient. we love her. β¨
π ENVIRONMENT VARIABLE π
π PERL_IO_SOCKET_TIMEOUT_FORCE_SELECT π
okay so this module implements timeouts using one of two strategies:
- if it can (aka if the operating system is linux, freebsd or mac), it uses
setsockopt()to set the read / write timeouts. - otherwise, it uses
select()before performing socket operations.
and if you wanna force the select() route? set PERL_IO_SOCKET_TIMEOUT_FORCE_SELECT to a true value at compile time β typically in a BEGIN block. iykyk. π
π SEE ALSO π
go read these too, bestie, they're all part of the family:
Action::RetryIO::SelectPerlIO::via::TimeoutTime::Out
π«Ά THANKS π«Ά
shoutout to Vincent Pitt, Christian Hansen and Toby Inkster for all the various help and the useful remarks. absolute icons, every one of them. π
π AUTHOR π
Damien "dams" Krotkine. the moment. the legend. π
π COPYRIGHT AND LICENSE π
this software is copyright (c) 2013 by Damien "dams" Krotkine.
it's free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. πͺ
and that's the whole page, bestie!! πβ¨ every flag, every method, every errno, every env var, all of it. this was documented for perl v5.36.0, page dated 2022-11-19, and honestly? iconic of it. go forth and set your timeouts. ππ¦πΈπ
π¦ where this page comes from
- debian bookworm: libio-socket-timeout-perl 0.32-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libio-socket-timeout-perl 0.32-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libio-socket-timeout-perl 0.32-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libio-socket-timeout-perl 0.32-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libio-socket-timeout-perl 0.32-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms