POE::Kernel's delay() method makes short work of a periodic task. Simply call it again from the delayed event's handler.
#!/usr/bin/perl -w use strict; use POE; use Time::HiRes qw(time); POE::Session->create( inline_states => { _start => sub { $_[KERNEL]->delay(tick => 1); }, tick => sub { print "tick at ", time(), "\n"; $_[KERNEL]->delay(tick => 1); }, }, ); POE::Kernel->run(); exit 0;
Here's what the program displays as it runs:
tick at 1005345715.2626 tick at 1005345716.27214 tick at 1005345717.28219 tick at 1005345718.2922 tick at 1005345719.30226 tick at 1005345720.31235 tick at 1005345721.32225 tick at 1005345722.33228
On an Athlon 1GHz, POE's overhead adds about 1/100 second to the "tick" event's interval. This delay will vary according to a system's processor speed, operating system, and load.
That 1/100 second may be insignificant for most programs, but it equates to a loss of about 15 minutes per day. The loss is inversely proportional to the delay period.
Delay Daily loss ========== ==================== 1 second about 14 1/2 minutes 1 minute about 14 1/3 seconds 1 hour about 1/4 second
The loss can be avoided altogether by keeping track of the next alarm time and using alarm() instead of delay. POE's overhead will still cause some latency between the ideal event time and the actual dispatch time, but the following program compensates for it.
This one-second timer program keeps the next alarm time in the HEAP and sets an absolute alarm for that time. Since the next alarm time increases in a constant fashion, so does the dispatch time.
#!/usr/bin/perl -w use strict; use POE; use Time::HiRes qw(time); POE::Session->create( inline_states => { _start => sub { $_[HEAP]->{next_alarm_time} = int(time()) + 1; $_[KERNEL]->alarm(tick => $_[HEAP]->{next_alarm_time}); }, tick => sub { print "tick at ", time(), "\n"; $_[HEAP]->{next_alarm_time}++; $_[KERNEL]->alarm(tick => $_[HEAP]->{next_alarm_time}); }, }, ); POE::Kernel->run(); exit 0;
The corresponding runtime output shows a 1/100 to 1/50 second lag between each alarm's due time and the actual dispatch time, but the average interval between events is 1 second.
tick at 1005346468.01947 tick at 1005346469.01953 tick at 1005346470.01965 tick at 1005346471.01977 tick at 1005346472.0099 tick at 1005346473.01008 tick at 1005346474.01015 tick at 1005346475.01025
For more advanced recurring alarms, see [POE::Component::Schedule] and [POE::Component::Cron].