Skip Menu |

This queue is for tickets about the Schedule-Cron CPAN distribution.

Report information
The Basics
Id: 69177
Status: open
Priority: 0/
Queue: Schedule-Cron

People
Owner: Nobody in particular
Requestors: rene [...] margar.fr
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 1.01_3
Fixed in: (no value)



Subject: Timeshift option
This is not a bug but a enhancement I did for the Schedule::Cron module to fit my needs : I needed to add what I called a timeshift to the main cron clock to shift all scheduled jobs in the future or in the past. I am using several perl scripts running Schedule::Cron concurrently and using similar crontabs (each one with different accounts/permissions). That can make many jobs launched exactly at the same time creating heavy CPU load. By shifting by some seconds or minutes internal Schedule::Cron clock I can avoid those massive launches without altering the crontabs. I added a new option to the object creator : $cron = new Schedule::Cron($dispatcher, timeshift => $ts); Default is 0 if option is not provided. I added a new public method to dynamically change the timeshift : $cron->set_timeshift($ts) Modify global time shift for all timetable. The timeshift is subbed from localtime to calculate next execution time for all scheduled jobs. ts parameter must be in seconds. Default value is 0. Negative values re allowed to shift time in the past. Returns actual timeshift in seconds. Example: $cron->set_timeshift(120); Will delay all jobs 2 minutes in the future. Bug: My implementation does not rebuild the job list after changing dynamically the timeshift. So next job execution is still using the previous timeshift value. Roland, you can add it to your code if you want and if you feel that it does not break the module. I give you a patch against 1.01_3 to add the timeshift functionnality.
Subject: cron-timeshift.patch
--- D:/OSP/lib/Schedule/Cron_1.01_b3.pm ven. 3 juin 2011, 10:09:04 +++ D:/OSP/lib/Schedule/Cron.pm mer. 29 juin 2011, 10:22:39 @@ -363,9 +363,11 @@ die "Dispatcher not a ref to a subroutine" unless ref($dispatcher) eq "CODE"; my $cfg = ref($_[0]) eq "HASH" ? $_[0] : { @_ }; $cfg->{processprefix} = "Schedule::Cron" unless $cfg->{processprefix}; + my $timeshift = $cfg->{timeshift} || 0; my $self = { cfg => $cfg, dispatcher => $dispatcher, + timeshift => $timeshift, queue => [ ], map => { } }; @@ -878,7 +880,7 @@ die "No more jobs to run\n"; } my ($index,$time) = @{shift @{$self->{queue}}}; - my $now = time; + my $now = time + $self->{timeshift}; my $sleep = 0; if ($time < $now) { @@ -917,7 +919,7 @@ } else { sleep($sleep); } - $sleep = $time - time; + $sleep = $time - (time + $self->{timeshift}); } $self->_execute($index,$cfg); @@ -1162,6 +1164,33 @@ } } +=item $cron->set_timeshift($ts) + +Modify global time shift for all timetable. The timeshift is subbed from localtime +to calculate next execution time for all scheduled jobs. + +ts parameter must be in seconds. Default value is 0. Negative values are allowed to +shift time in the past. + +Returns actual timeshift in seconds. + +Example: + + $cron->set_timeshift(120); + + Will delay all jobs 2 minutes in the future. + +=cut + +sub set_timeshift +{ + my $self = shift; + my $value = shift || 0; + + $self->{timeshift} = $value; + return $self->{timeshift}; +} + # ================================================== # PRIVATE METHODS: # ================================================== @@ -1289,7 +1318,7 @@ my $new_time = $self->get_next_execution_time($entry->{time}); # Check, whether next execution time is *smaller* than the current time. # This can happen during DST backflip: - my $now = time; + my $now = time + $self->{timeshift}; if ($new_time <= $now) { dbg "Adjusting time calculation because of DST back flip (new_time - now = ",$new_time - $now,")" if $DEBUG; # We are adding hours as long as our target time is in the future @@ -1313,7 +1342,7 @@ my $now = shift; my $expanded = shift; - my $offset = ($expanded->[5] ? 1 : 60); + my $offset = ($expanded->[5] ? 1 : 60) + $self->{timeshift}; my ($now_sec,$now_min,$now_hour,$now_mday,$now_mon,$now_wday,$now_year) = (localtime($now+$offset))[0,1,2,3,4,6,5]; $now_mon++;
Good idea. I added the path (+ a test) and this will be availbable with 1.02. 'hope the license for you contribution (artisstic)
is ok for you.

On Wed Jun 29 08:42:16 2011, rene@margar.fr wrote:
Show quoted text
> This is not a bug but a enhancement I did for the Schedule::Cron module
> to fit my needs :
>
> I needed to add what I called a timeshift to the main cron clock to
> shift all scheduled jobs in the future or in the past. I am using
> several perl scripts running Schedule::Cron concurrently and using
> similar crontabs (each one with different accounts/permissions). That
> can make many jobs launched exactly at the same time creating heavy CPU
> load. By shifting by some seconds or minutes internal Schedule::Cron
> clock I can avoid those massive launches without altering the crontabs.
>
> I added a new option to the object creator :
>
> $cron = new Schedule::Cron($dispatcher, timeshift => $ts);
>
> Default is 0 if option is not provided.
>
>
> I added a new public method to dynamically change the timeshift :
>
> $cron->set_timeshift($ts)
>
> Modify global time shift for all timetable. The timeshift is subbed from
> localtime to calculate next execution time for all scheduled jobs.
>
> ts parameter must be in seconds. Default value is 0. Negative values re
> allowed to shift time in the past.
>
> Returns actual timeshift in seconds.
>
> Example:
>
> $cron->set_timeshift(120);
> Will delay all jobs 2 minutes in the future.
>
> Bug:
> My implementation does not rebuild the job list after changing
> dynamically the timeshift. So next job execution is still using the
> previous timeshift value.
>
> Roland, you can add it to your code if you want and if you feel that it
> does not break the module.
>
> I give you a patch against 1.01_3 to add the timeshift functionnality.