WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 3 years ago

#11800 new defect (bug)

doubled execution of cron jobs

Reported by: neoxx Owned by: westi
Milestone: Future Release Priority: normal
Severity: normal Version: 2.9.1
Component: Cron API Keywords: cron
Focuses: Cc:

Description

Hi,

as I've already mentioned in ticket #11505 , cron-jobs occasionally get executed twice (e.g. daily backup arrives two times).

I've changed the code according to the patch attachment:ticket:11505:ticket-11505-stop-gap.patch (which derives from http://wpengineer.com/ping-problem/) after my comment:ticket:11505:49 and had no doubles within this time period. This week I've upgraded to WP 2.9.1 and since then backups arrive two, sometimes three times, again.

Looking at the changes from 2.9 to 2.9.1, I have no other explanation for this behavior. - Maybe we should consider having a closer look again on this patch attachment:ticket:11505:ticket-11505-stop-gap.patch .

Greetz,
Berny

Change History (6)

comment:1 follow-up: miqrogroove4 years ago

Idea for a fix: Create a proper token for each future job. In wp-cron.php, consume that token at the top of the script. Since the token can only be used once, any races are broken and the concurrent jobs may self-quit.

comment:2 dd324 years ago

Since the token can only be used once

How do you mark a token as expired?

By setting it in the database? A flag is already set that cron is in progress, If thats true when the new script starts, it should bail from memory. unforunately, multiple scripts can try that check at the same time and all end up running..

comment:3 in reply to: ↑ 1 westi4 years ago

  • Milestone changed from 2.9.2 to Future Release

Replying to miqrogroove:

Idea for a fix: Create a proper token for each future job. In wp-cron.php, consume that token at the top of the script. Since the token can only be used once, any races are broken and the concurrent jobs may self-quit.

This means we can only process on cron task per page load of wp-cron.php.

For me one of the biggest problems with cron at the moment is that it is all stored in a single option.

This makes it hard to do atomic actions on the data - especially if people are using an object cache / running across multiple servers.

You can't atomically add/remove a cron task at the moment.

I think it would be best to look into fixing this problem rather than papering over the cracks.

The best solution here is probably to split the cron jobs off so they are stored as single job per row in the db.

Moving out of 2.9.2 as I think this needs a structural fix.
Moving to Future Release for now as there is no patch and no guarantee it will be fixed in the 3.0 dev cycle.

If someone wants to attempt this I would be happy to review patches and discuss ideas.

comment:4 miqrogroove4 years ago

How do you mark a token as expired?

Tokens are consumed by deleting them. Expired usually implies that the token becomes invalid after a certain time.

This means we can only process on cron task per page load of wp-cron.php.

No it doesn't.

comment:5 mintindeed3 years ago

  • Cc gabriel.koen@… added

The patch I created for #15148 creates a cron table with one row per job. The primary key field is a token using a hash of the timestamp, hook, and arguments. The schedule cron function will blindly try and insert any job you tell it, but since the primary key is a hash of those params, duplicate entries will simply fail to be inserted into the database (without a separate query to check if they already exist).

There's also a status field, so theoretically wp-cron.php could be modified to spawn off multiple processes (1 for each job) which would then update the status of the job they're working on (pending, processing, completed). Basically laying the groundwork for a real job queue, if that's the direction you want to take it.

comment:6 agupta_pmc3 years ago

  • Cc agupta_pmc added
Note: See TracTickets for help on using tickets.