#42660 closed defect (bug) (invalid)
Single event scheduler
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 4.9 |
Component: | Cron API | Keywords: | reporter-feedback |
Focuses: | Cc: |
Description
When I set single event for wp_cron for example 2017-11-22 00:00:00 it is executed than more one time. I think it should be only one time and if wordpress doesn't have users at the same time first user who open wordpress site will triggered wp cron. Example 0 users 2017-11-22 00:00:00 on website and wp_cron is not executed , 2017-11-22 00:15:27 - 1 user on wordpress website and cron is executed only one time.
Change History (21)
#1
in reply to:
↑ description
@
6 years ago
#2
@
6 years ago
<?php $next_run = strtotime('2017-11-22 10:00'); wp_clear_scheduled_hook('single_action'); wp_schedule_single_event($next_run, 'single_action');
#3
@
6 years ago
- Component changed from General to Cron API
- Focuses performance removed
- Keywords reporter-feedback added
Unfortunately, the WordPress cron api isn't guaranteed to only run once, code should expect that it's possible for it to happen - however it's extremely unlikely to happen.
We've improved things greatly over what it used to be #17462 & #19700, I don't think I've heard of major complaints since then.
Running an external cron implementation such as Cavalcade can help, especially when the tasks are long running.
Given your code in the above comment, how are you running that? Is there a chance that the job is simply being scheduled twice?
What do you see if you run it like so: Do you get multiple timestamps being passed as the first parameter?
wp_schedule_single_event( time(), 'single_action', array( microtime(1) ) );
#4
follow-up:
↓ 6
@
6 years ago
@dd32 , no it is not working as well
<?php wp_schedule_single_event( time(), 'single_action', array( microtime(1) ) );
And when I open https://wptest.dev/wp-cron.php?doing_wp_cron via crontab 5 times I got 5 executed cron events. It must be only once.
#6
in reply to:
↑ 4
@
6 years ago
- Severity changed from major to normal
Replying to skarabeq:
And when I open https://wptest.dev/wp-cron.php?doing_wp_cron via crontab 5 times I got 5 executed cron events. It must be only once.
You're bypassing the cron locks by doing that, and as a result, the cron task being fired multiple times is expected.
The cron should be only triggered by calling spawn_cron()
.
If you're using an external trigger for cron tasks by calling the cron url directly then you'll need to handle it yourself some other way.
I'm going to mark the ticket as invalid
as it sounds like this is purely due to you triggering the cron manually, if you can experience cron tasks running multiple times, via spawn_cron()
(Which is what WordPress uses) feel free to re-open the ticket with detailed information we can use to duplicate it.
#8
@
6 years ago
@dd32 I'm not sure you are right. Same as result when I set cron
<?php wp_schedule_single_event( time(), 'single_action', array( microtime(1) ) );
and then open base url https://wptest.dev or open https://wptest.dev/wp-admin wp cron is triggered.
I think doesn't matter what I open for triggered wp cron. So If I have 100 users and they open home page, the wordpress will triggered 100 times this single event wp cron. It should be only once.
#9
@
6 years ago
- Severity changed from major to normal
That's expected behaviour when use wp_schedule_single_event()
and time()
. You have to use a fixed time and/or register it only once to schedule the event only once. You also might want to use wp_next_scheduled()
.
<?php if ( ! wp_next_scheduled( 'single_action' ) ) { wp_schedule_single_event( strtotime( '2017-11-22 11:00' ), 'single_action' ); }
#10
follow-up:
↓ 12
@
6 years ago
- Severity changed from normal to major
@ocean90 with this code:
<?php if ( ! wp_next_scheduled( 'single_action' ) ) { wp_schedule_single_event( strtotime( '2017-11-22 11:00' ), 'single_action' ); }
isn't works like as expect. Still triggered event on every refresh on website (doesn't matter where I'm)
This ticket was mentioned in Slack in #core by skarabeq. View the logs.
6 years ago
#12
in reply to:
↑ 10
@
6 years ago
- Milestone Awaiting Review deleted
- Resolution set to invalid
- Severity changed from major to normal
- Status changed from new to closed
Replying to skarabeq:
@ocean90 with this code:
<?php if ( ! wp_next_scheduled( 'single_action' ) ) { wp_schedule_single_event( strtotime( '2017-11-22 11:00' ), 'single_action' ); }isn't works like as expect. Still triggered event on every refresh on website (doesn't matter where I'm)
I think what is happening here is:
- Pageload 1: See's there's no
single_action
scheduled, so queues it up. Later in the pageload it sees there's crons that need running, so it spawns the cron process.- Cron pageload runs in background. removes cron entry.
- Pagelaod 2: The cron run has already processed the cron and removed its entry from the database, so
wp_next_scheduled( 'single_action' )
is once againfalse
, so it queues it up again to run- Cron pageload runs in the background again
rinse repeat.
In your case, you should -conditionally- call wp_schedule_single_event()
when a certain circumstance is true (For example, if ( isset( $_POST['schedule-the-cron'] ) ) { wp_schedule_single_event( time(), 'single_action' ); }
).
This is a hastily written, and insecure, but here's an example plugin which shows an implementation where the cron only fires once, in response to a user action triggering it to run:
https://gist.github.com/dd32/d1091e4f6316dba126814b5d3ce559bb
I hope this helps set you on the right direction.
I'm marking this ticket as invalid as there's nothing which can be used to point to a core bug, discussion can still occur while the ticket is closed, please do not re-open the ticket unless you have information which can be used to reproduce a bug in core.
#13
@
6 years ago
@dd32 , this is good solution, but when this default function wp_schedule_single_event
isn't works as a single event , his name is wrong. My solution is similar to yours solution in gist.
#14
@
6 years ago
I can see where it may be confusing, It schedules a single (once-off) task to run, this is in comparison to wp_schedule_event()
which schedules a recurring (non-single) event which re-queues itself.
#15
@
6 years ago
wp_schedule_single_event
is run more than one time when you have no additional check. For me single event is mean only one time run without additional checks.
#16
@
5 years ago
- Resolution invalid deleted
- Severity changed from normal to major
- Status changed from closed to reopened
This ticket was mentioned in Slack in #core by skarabeq. View the logs.
5 years ago
#19
@
5 years ago
- Resolution set to invalid
- Severity changed from major to normal
- Status changed from reopened to closed
As stated
I can see where it may be confusing, It schedules a single (once-off) task to run, this is in comparison to wp_schedule_event() which schedules a recurring (non-single) event which re-queues itself.
Nothing here indicates a bug.
#20
@
5 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
@dd32 What is not clear ? I clearly explained more than one times when I use wp_schedule_single_event
it is running more than one time. If I have one user on the website and he refresh 10 times web page the cron will be executed 10 times, if I have 100 users with 10 refreshes on website the cron will be executed 1000 times. Could you please check this in details, because this is bug!
Again I will paste my simple code:
<?php $time = strtotime(date('Y-m-d 00:00:00', strtotime('next Tuesday'))); wp_schedule_single_event($time, 'hook_of_cron_job');
#21
@
5 years ago
- Resolution set to invalid
- Status changed from reopened to closed
Hi @skarabeq how are you?
A event scheduled with wp_schedule_single_event
will run just one time for each time you scheduled it (as @dd32 explained here).
You have to make sure you will not call wp_schedule_single_event
function after the event runned.
If you want a event run just really once (and never again) the best way is to run wp_schedule_single_event
in a action will run just once (like activating a plugin). If it's not possible, another solution would be add a entry in database (before it run to avoid parallel events and after it run to say "it's done: never schedule this again").
P.S: A video with a test you can do to check it's not a Core bug.
@skarabeq What code for cron setup you used, can you paste it here to understand it better?
Replying to skarabeq: