Tom Molesworth
and 1 contributors

NAME

IO::AsyncX::SharedTimer - provides IO::Async timers which sacrifice accuracy for performance

VERSION

version 0.001

SYNOPSIS

 # Needs to be added to a loop before you can
 # call any other methods
 my $loop = IO::Async::Loop->new;
 $loop->add(
  my $timer = IO::AsyncX::SharedTimer->new(
   # Combine timers into 50ms buckets, and
   # use cached value for ->now with 50ms expiry
   resolution => 0.050,
  )
 );

 # Report current time, accurate to ~50ms (defined
 # by the resolution parameter, as above)
 use feature qw(say);
 say "Time is roughly " . $timer->now;

 # Set a timeout for ~30s on an I/O operation
 Future->wait_any(
  $client->read_until(qr/\n/),
  $timer->timeout_future(after => 30)
 )->get;

DESCRIPTION

This module provides various time-related utility methods for use with larger IO::Async applications.

In situations where you have many related timers - connection expiry, for example - there may be some overhead in having each of these in the timer priority queue as a separate event. Sometimes the exact trigger time is not so important, which is where this class comes in. You get to specify an accuracy, and all timers which would occur within the same window of time will be grouped together as a single timer event.

This may reduce calls to poll/epoll and timer management overhead, but please benchmark the difference before assuming that this module will be worth using - for some applications the overhead this introduces will outweigh any potential benefits.

One benchmark gave the following results for 1ms resolution across 100 timers set to rand(1) seconds:

            Rate      normal   shared
 normal    32.9/s        --      -50%
 shared    65.7/s      100%        --

See the examples/ directory for code.

METHODS

configure

Change the current resolution.

Takes one named parameter:

  • resolution - the resolution for timers and "now", in seconds

resolution

Returns the current resolution.

now

Returns an approximation of the current time.

On first call, it will return (and cache) the value provided by the Time::Hires time function.

Subsequent calls will return this same value. The cached value expires after "resolution" seconds - note that the expiry happens via the event loop so if your code does not cede control back to the main event loop in a timely fashion, the cached value will not expire. Put another way: the value will be cached for at least "resolution" seconds.

There's a good chance that the method call overhead will incur a heavier performance impact than just calling Time::HiRes time directly. As always, profile and benchmark first.

Example usage:

 my $start = $timer->now;
 $loop->run;
 my $elapsed = 1000.0 * ($timer->now - $start);
 say "Operation took about ${elapsed}ms to complete.";

delay_future

Returns a Future which will resolve after approximately "resolution" seconds.

See the delay_future documentation in IO::Async::Loop for more details.

timeout_future

Returns a Future which will fail after approximately "resolution" seconds.

See the delay_future documentation in IO::Async::Loop for more details.

INHERITED METHODS

IO::Async::Notifier

add_child, adopt_future, can_event, children, configure_unknown, debug_printf, get_loop, invoke_error, invoke_event, loop, make_event_cb, maybe_invoke_event, maybe_make_event_cb, new, notifier_name, parent, remove_child, remove_from_parent

AUTHOR

Tom Molesworth <cpan@perlsite.co.uk>

LICENSE

Copyright Tom Molesworth 2014-2015. Licensed under the same terms as Perl itself.