package IO::AsyncX::SharedTimer; # ABSTRACT: Low-accuracy shared timers for IO::Async use strict; use warnings; use parent qw(IO::Async::Notifier); our $VERSION = '0.001'; =head1 NAME IO::AsyncX::SharedTimer - provides L timers which sacrifice accuracy for performance =head1 VERSION version 0.001 =head1 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; =head1 DESCRIPTION This module provides various time-related utility methods for use with larger L 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. =cut use Time::HiRes (); use curry::weak; =head1 METHODS =cut =head2 configure Change the current resolution. Takes one named parameter: =over 4 =item * resolution - the resolution for timers and L, in seconds =back =cut sub configure { my ($self, %args) = @_; if(exists $args{resolution}) { $self->{resolution} = delete $args{resolution}; } $self->SUPER::configure(%args); } =head2 resolution Returns the current resolution. =cut sub resolution { shift->{resolution} } =head2 now Returns an approximation of the current time. On first call, it will return (and cache) the value provided by the L C