Time::Out(3pm)

πŸ“¦
version 1.0.0 Β· 6 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

✨ Time::Out πŸ’–

okay so bestie, this is the page for Time::Out, from the User Contributed Perl Documentation section of the manual (that's the 3pm part, iykyk) β€” and it does exactly one iconic thing: it lets you easily timeout long running operations. periodt. πŸŽ€


🌸 NAME 🌸

Time::Out β€” easily timeout long running operations πŸ•πŸ’…


✨ SYNOPSIS ✨

use Time::Out qw( timeout );

timeout $timeout => sub {
  # your operation is implemented here and will be interrupted
  # if it runs for more than $timeout seconds
};
if ( $@ ) {
  # operation timed-out
}

πŸ¦‹ DESCRIPTION πŸ¦‹

so the Time::Out module hands you a super easy interface to alarm(2) based timeouts. and yes, nested timeouts are supported β€” go off, recursion queen πŸ‘‘

The module exports the timeout() function by default. And here's the cute part: the function returns whatever the code placed inside the subroutine reference returns 🫢

use Time::Out qw( timeout );

my $result = timeout 5 => sub {
  return 7;
};
# $result == 7

And if Time::Out sees that Time::HiRes has been loaded, it will use that alarm() function instead of the default one β€” if available β€” which means you can use float timeout values effectively. no cap. πŸ“

use Time::HiRes qw();
use Time::Out   qw( timeout );

timeout 3.1416 => sub {
  # ...
};

πŸ’€ CAVEATS πŸ’€

bestie. sit down. we gotta talk about the fine print. it's giving "read the docs or perish" πŸ™ˆ

Blocking I/O on MSWin32 😭

alarm(2) doesn't interrupt blocking I/O on MSWin32, so timeout() won't do that either. that's just the vibe over there, sorry. πŸ’€

@_ 😳

One drawback to using timeout() is that it masks @_ in the affected code. Why? Because the affected code is actually wrapped inside another subroutine that provides its own @_. sneaky.

You can get around this by specifically passing your @_ (or whatever you want for that matter) to timeout() like this:

use Time::Out qw( timeout );

sub foo {
  timeout 5, @_ => sub {
    @_;
  };
}
my @result = foo( 42, "Hello, World!" );
# @result == ( 42, "Hello, World!" );

Eval inside timeout 🧚

If the affected code has its own exception handling using Try::Tiny for example, the catch block has to be amended in a way so that it will rethrow an exception, if it refers to a timeout:

use Scalar::Util qw( blessed  );
use Time::Out    qw( timeout );
use Try::Tiny    qw( catch try );

timeout 5, sub {
  try {
    select( undef, undef, undef, 7 );
    die "bad\n";
  } catch {
    # rethrow exception, if it refers to a timeout
    die $_ if defined blessed $_ and $_->isa( 'Time::Out::Exception' );
    # handle all other exceptions
  }
};

πŸ‘€ SEE ALSO πŸ‘€

alarm(2), Sys::AlarmCall


πŸ‘‘ AUTHORS πŸ‘‘

Sven Willenbuecher, <sven.willenbuecher@gmx.de> πŸ’œ

Patrick LeBoutillier, <patl@cpan.org> 🌈


This software is copyright (c) 2005-2008 Patrick LeBoutillier, 2023 by Sven Willenbuecher.

This is 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 πŸ’… documented by perl v5.40.0, dated 2024-10-28, filed under Time::Out(3pm) β€” go forth and timeout responsibly, mwah 🫢✨

πŸ“¦ where this page comes from