X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FPlugin%2FScheduler%2FEvent.pm;fp=lib%2FCatalyst%2FPlugin%2FScheduler%2FEvent.pm;h=76a96f7a0a604ab4471263f6de170e94d454b316;hb=247e43e21a5f08daecc0cbb128e455dfb234f481;hp=92ae78818a4a13b301c308e1daad761a1f210328;hpb=945fdd23e20de8a28bbe0f3ea49d768b19a9a394;p=catagits%2FCatalyst-Plugin-Scheduler.git diff --git a/lib/Catalyst/Plugin/Scheduler/Event.pm b/lib/Catalyst/Plugin/Scheduler/Event.pm index 92ae788..76a96f7 100755 --- a/lib/Catalyst/Plugin/Scheduler/Event.pm +++ b/lib/Catalyst/Plugin/Scheduler/Event.pm @@ -258,17 +258,39 @@ Returns the time that this event is due to be run as a C object =cut -sub next_run_as_dt { - my $self = shift; - - if( $self->set ) { - my $dt = DateTime->from_epoch( - epoch => $self->_last_check_time, - time_zone => $Base->_config('time_zone'), - ); - return $self->set->next( $dt ); - } - return; +{ my %cache = (); + + sub next_run_as_dt { + my $self = shift; + + ### the time for the next run is EITHER based on the last_run time + ### ie, if the last run time is 61 seconds ago, and it's a per minute + ### schedule, the 'next run' should return a time of 1 second ago. + ### similarly, if the last run time is 2 hours ago, the 'next run' + ### should return a time of 1h59mins ago, which again means it's due. + ### The 'last_run' may be 0 (or better yet, undef), in that case, + ### we assume the last run time was NOW. The problem is that if we + ### keep asking the 'next_run' time on subsequent requests, it will + ### always be based on 'NOW' + 1 minute (for events running every + ### minute), which will always be in the future. Hence we cache + ### the answer the first time 'last_run' returns false (ie, never + ### run) and use that answer as a fallback, meaning that if we come + ### back later (say, 65 seconds later), the 'next run' will be based + ### on NOW - 65 + 1 minute, which is 5 seconds ago, and hence the + ### event will trigger... + my $epoch = $self->last_run || + $cache{$self} || + do { $cache{$self} = time }; + + if( $self->set ) { + my $dt = DateTime->from_epoch( + epoch => $epoch, + time_zone => $Base->_config('time_zone'), + ); + return $self->set->next( $dt ); + } + return; + } } =head2 $bool = $event->run( ... )