Damien Krotkine > IO-Socket-Timeout-0.15 > IO::Socket::Timeout

Download:
IO-Socket-Timeout-0.15.tar.gz

Dependencies

Annotate this POD

View/Report Bugs
Module Version: 0.15   Source   Latest Release: IO-Socket-Timeout-0.27

NAME ^

IO::Socket::Timeout - IO::Socket with read/write timeout

VERSION ^

version 0.15

SYNOPSIS ^

  use IO::Socket::With::Timeout;

  # creates a IO::Socket::INET::With::Timeout object
  my $socket = IO::Socket::INET->new::with::timeout( Timeout => 2,
                                                     ReadTimeout => 0.5,
                                                     # other standard arguments );

  my $socket = IO::Socket::UNIX->new::with::timeout( Timeout => 2,
                                                     ReadTimeout => 0.5,
                                                     WriteTimeout => 0.5,
                                                     # other standard arguments );

  my $socket = IO::Socket::INET->new::with::timeout( Timeout => 2,
                                                     ReadWriteTimeout => 0.5,
                                                     # other standard arguments );

  # When using the socket:
  use Errno qw(ETIMEDOUT);
  print $socket $request;
  my $response = <$socket>;
  if (!defined $response && 0+$! == ETIMEDOUT) {
    die "timeout reading on the socket";
  }

DESCRIPTION ^

IO::Socket provides a way to set a timeout on the socket, but the timeout will be used only for connection, not for reading / writing operations.

This module provides a way to set a timeout on read / write operations on an IO::Socket instance, or any IO::Socket::* modules, like IO::Socket::INET.

CONSTRUCTORS ^

new::with::timeout

To be able to work with any class that is or inherits from IO::Socket, the interface of this module is a bit unusual.

IO::Socket::INET-new::with::timeout(...)> will return an instance of IO::Socket::INET, as if it had been called with IO::Socket::INET-new(...)>. However, it'll apply some mechanism on the resulting socket object so that it times out on read, write, or both.

The way the socket will timeout ( on connection, read, write, how long), can be specified with these parameters:

Timeout

This is the default parameter that already exists in IO::Socket. If set to a value, the socket will timeout at connection time.

ReadTimeout

If set to a value, the socket will timeout on reads. Value is in seconds, floats accepted.

WriteTimeout

If set to a value, the socket will timeout on writes. Value is in seconds, floats accepted.

ReadWriteTimeout

If set to a value, the socket will timeout on reads and writes. Value is in seconds, floats accepted. If set, this option superseeds ReadTimeout and WriteTimeout.

socketpair::with::timeout

There is an other way to create sockets from scratch, via socketpair. As for the new constructor, this module provides its counterpart with timeout feature.

IO::Socket::INET-socketpair::with::timeout(...)> will return two instances of IO::Socket::INET, as if it had been called with IO::Socket::INET-socketpair(...)>. However, it'll apply some mechanism on the resulting socket object so that it times out on read, write, or both.

CHANGE SETTINGS AFTER CREATION ^

You can change the timeout settings of a socket after it has been instanciated. These functions are part of PerlIO::via::Timeout. Check its documentation for more details.

  use IO::Socket::With::Timeout;
  # create a socket with read timeout
  my $socket = IO::Socket::INET->new::with::timeout( Timeout => 2,
                                                     ReadTimeout => 0.5,
                                                     # other standard arguments );

  use PerlIO::via::Timeout qw(:all);
  # change read_timeout to 5 and write timeout to 1.5 sec
  read_timeout($socket, 5)
  write_timeout($socket, 1.5)
  # actually disable the timeout for now
  disable_timeout($socket)
  # when re-enabling it, timeouts value are restored
  enable_timeout($socket)

WHEN TIMEOUT IS HIT ^

When a timeout (read, write) is hit on the socket, the function trying to be performed will return undef, and $! will be set to ETIMEOUT.

The socket will be marked as invalid internally, and any subsequential use of it will return undef, and $! will be set to ECONNRESET.

Why invalid the socket ? If you read a socket, waiting for message A, and hit a timeout, if you then reuse the socket to read a message B, you might receive the answer A instead. There is no way to properly discard the first message, because the sender mught not be reachable (that's probably why you got a timeout in the first place). So after a timeout failure, it's important that you recreate the socket.

You can import ETIMEOUT and ECONNRESET by using POSIX:

  use Errno qw(ETIMEDOUT ECONNRESET);

IF YOU NEED TO RETRY ^

If you want to implement a try / wait / retry mechanism, I recommend using a third-party module, like Action::Retry. Something like this:

  my $socket;

  my $answer;
  my $action = Action::Retry->new(
    attempt_code => sub {
        # (re-)create the socket if needed
        $socket && ! $socket->error
          or $socket = IO::Socket->new::with::timeout(ReadTimeout => 0.5);
        # send the request, read the answer
        $socket->print($_[0]);
        defined($answer = $socket->getline) or die $!;
        $answer;
    },
    on_failure_code => sub { die 'aborting, to many retries' },
  );

  my $reply = $action->run('GET mykey');

SEE ALSO ^

Action::Retry, IO::Select, PerlIO::via::Timeout, Time::Out

THANKS ^

Thanks to Vincent Pitt, Christian Hansen and Toby Inkster for various help and useful remarks.

AUTHOR ^

Damien "dams" Krotkine

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2013 by Damien "dams" Krotkine.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

syntax highlighting: