Reputation: 2927
I am having a difficult time setting up a Cron job to run once a day at a set time. Here's what I have in my module's config:
<crontab>
<jobs>
<sorting_flushcache>
<schedule><cron_expr>0 16 * * *</cron_expr></schedule>
<run><model>sorting/observer::flushProductCacheCron</model></run>
</sorting_flushcache>
</jobs>
</crontab>
From what I know about cron jobs, that should run at 5pm based on my local timezone. However, it NEVER works. If I instead set the cron_expr to * 16 * * *
it schedules a job every minute for the entire hour (as you'd expect).
I traced through the code and I think I found the problem but I don't know enough about cron scheduling and how this is really supposed to work so I'm hoping someone can help me understand what's wrong and how to make my job work.
Mage_Cron_Model_Schedule is the brains of the beast. When the cron.php script is called by the server's crontab schedule it dispatches an event that this class catches and does its work. Among other things it pulls in the config and attempts to schedule the upcoming cron jobs. Inside public function trySchedule($time)
it calls matchCronExpression
, passing it the piece of the cron expression in question along with the value of the current time corresponding with that piece of the cron expression. For example, it compares the first part of the cron_expr (the minutes part) to the minutes of the current timestamp. At the end of the matchCronExpression
function it returns a boolean value like so:
return ($num>=$from) && ($num<=$to) && ($num%$mod===0);
In my case, my cron_expr is 0 16 * * *
. Since I don't have any ranges or */5
type stuff for my minutes portion, it is comparing the exact value I set against the exact value of the current timestamp. This means it will ONLY return true if it happened to run the cron script at the exact minute that this job should be scheduled.
Again, I am not a cron expert but this doesn't seem right to me. How, then, is one supposed to schedule a job to run once a day if you can't predict the exact minute that the cron scheduler will run the script? I really hope I'm missing something...can anyone help?
-- CRON CONFIG INFO --
generate schedules every: 5
schedule ahead for: 10
missed if not run within: 20
success history lifetime: 60
failure history lifetime: 600
Upvotes: 5
Views: 1990
Reputation: 2927
I may have found a "solution" to this issue but I'm not sure the possible impact this might have. Hopefully someone else can chime in to confirm or provide a better answer.
I changed my Cron Config in Magento as follows:
generate schedules every: 1
schedule ahead for: 5
missed if not run within: 20
history cleanup every: 30
success history lifetime: 60
failure history lifetime: 600
This seems to have done the trick. It now generates schedules every minute so it doesn't miss the window to scheduling my once-a-day event.
Any thoughts on this? I'm concerned that it's too much for the system to be generating cron schedules every minute. It should be able to handle it, but I'll have to do testing to confirm.
Anyone else have a similar experience? How did you solve it?
Upvotes: 3