5

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
Mageician
  • 2,918
  • 9
  • 43
  • 69
  • Server timezone, not your local timezone. – hakre Apr 19 '12 at 22:04
  • Whatever, that's not the point. As I mentioned in my post, if I change it to `* 16 * * *` it works....so it's not the semantics of which timezone I said I based it on. I simply doesn't work. – Mageician Apr 19 '12 at 22:06
  • Yeah looks broken. But what I read, the code quality of magneto ain't well. probably just something shitbacked together to push the release and make it look sexy to be sold quick. – hakre Apr 19 '12 at 22:07
  • See cron_schedule table in database and cron settings in Admin System > Configuration > System – benmarks Apr 20 '12 at 00:58
  • @benmarks I should have mentioned I've checked all of that stuff. No entries in the cron_schedule for my module but others are. Not sure what the recommended settings are for the Magento cron config but I've added mine to the question. Any thoughts? – Mageician Apr 20 '12 at 04:57
  • Sorry if this is assumed, but have you verified that your config file is being parsed? I assume you've invalidated the configuration cache as well. Those two items are a prerequisite for moving forward, of course. – benmarks Apr 20 '12 at 10:49
  • @benmarks It's never good to assume, so no problem asking. Yes, everything is being parsed and all other aspects of the module are working. Further, as I mentioned in my question, if I change the cron config from `0 16 * * *` to `* 16 * * *` it adds an entry per minute to the cron_schedule. So it's reading everything. Check out the core code if you're curious. Unless I'm reading something incorrectly, it's destined to fail. Someone out there MUST have run into this before. Any ideas? – Mageician Apr 20 '12 at 16:38

1 Answers1

3

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?

Mageician
  • 2,918
  • 9
  • 43
  • 69
  • Well, this got the entries to start showing up in the cron_schedule table but it's not properly running my code. The method in my model called by cron is **flushProductCacheCron**. After it runs I check the DB and it has updated my table to reflect that it has processed the items that needed processing but it never actually flushed the cache. Are there limitations in what code can be run by a cron job? To test I set up a frontend controller to call the same method called by cron. When I load up that URL it works correctly. Only cron has the problem. What's going on here? – Mageician Apr 20 '12 at 18:13