Wordpress cron wp_schedule_single_event – action not always working
Asked Answered
O

5

10

I'm registering an event like:

wp_schedule_single_event( time(), 'do_custom_hook', array( $body ) );

Above that, I have added the following action:

add_action('do_custom_hook', 'process_custom_hook', 10);

function process_custom_hook($body){
    // custom code here
}

However, sometimes the process_custom_hook function fires, while other times, it simply doesn't (it fires most times, though. It's missed about 10%-20% of the time)

The event is always returning true, meaning that it must have registered.

Also, while testing, I made sure that the arguments (body) is always different.

Any reason why this may occur?

Occlude answered 24/2, 2020 at 10:51 Comment(10)
What's the purpose of scheduling a single event for "now"? Why don't you just execute process_custom_hook instead of scheduling the event? Also, did you really make sure $body was different each time and not accidentally the same in 10-20% of the cases?Arand
Okay. The thing is: these scheduled events aren't exactly run by a cron daemon.. they fire when users are viewing the page. If process_custom_hook contains blocking code, this will anyway run while a user is trying to load the page - thus, will still affect users' page load times. For such blocking requests there are two options: using AJAX so the user isn't directly affected by the processing time, or use a real cron job invoking a PHP file requiring wp-load.php and then performing the process_custom_hook stuff.Arand
From my research (wordpress.stackexchange.com/questions/141457/…) wp uses a parallel request, which will not block the user. Also, some testing I did using the sleep() function seems to show me that the function is indeed non-blocking.Occlude
In my experience, PHP's time() function is not always synced with Wordpress. You should use current_time('timestamp') or variations thereof when included in WP functionsDoncaster
@Doncaster thanks for the input, but that wasn't the issue, unfortunately. What's weird is that the wp_schedule_single_event function returns true, meaning, that it must have been scheduled, but doesn't run nor appear in the cron. Something must be telling it to skip the event... Is there maybe a maximum amount of times an event can be emitted in a given period of time? Or, should events be cleaned up (even though I schedule it only once, and they appear to be removed automatically after execution)?Occlude
"It's missed about 10%-20% of the time" - how do you know that? How are you tracking it?Thermoelectricity
As I've set up the hook to trigger when a product is updated, all I'm really doing is updating a product value and checking the output through logging. Unfortunately, I can't tell if it has to do with a number of updates happening in a certain interval or something like that, so it may not be the most scientific approach...Occlude
Please refer to this. I think it will help you rudrastyh.com/wordpress/wp_schedule_single_event.html Use strtotime('+10 minutes') instead time() pass whatever time you want.Archaeo
I think if you could share a bit more of your code, we could figure this out. How do you determine or ensure the $body is always different?Alicealicea
I'm experiencing exactly this same issue, and still don't find the root cause. @Occlude did you finally get it work?Spinescent
B
4

From the codex:

Note that scheduling an event to occur before 10 minutes after an existing event of the same name will be ignored, unless you pass unique values for $args to each scheduled event.

If your custom hook is only working some of the time, then this might be an avenue to look at. If you require the hook to be handled immediately, then it might be prudent to look at giving a hook a unique name, or passing unique values to the hook.

If you do not need your job to execute immediately, then you could look at utilising wp_next_scheduled() to determine when the job will next run, and set a job to run after the next scheduled job.

It's also worth noting that if this task is something which seems to have consistent logic behind it (as seems to be the case) - why not store the job information in to the database and run a cron job every 5-10 minutes to pick up any new jobs from the database and handle them as such? This would avoid needing to deal with the behaviour of wp_schedule_single_event().

Burnt answered 5/3, 2020 at 7:57 Comment(4)
Thanks for the answer. Some things I find weird: even passing the same arguments to the function multiple times within the 10 minute time-frame does seem to fire it (almost always). Thus, my testing doesn't really match the codex excerpt you posted. And yes, the hook is required to be handled immediately. How would I go about giving a hook a unique name for every execution? It may be worth noting that the arguments are key-value pairs where I made sure that at least one value always differed, but the keys are the same.Occlude
Addition: for testing, I passed another argument to the function consisting of 40 random characters to check if the args are the problem. Turns out, they aren't. The function still sometimes doesn't run...Occlude
You could run add_action() before passing a name into wp_schedule_single_event() and then remove the action with remove_action() at the end of the scheduled event, this is a suggestion and I am unsure initially if it would work across different requests (or with a cron system) so more research could be required there.Burnt
Yeah, from my quick test, this seems to cause some problems due to the different requests. I'll try to dig further...Occlude
A
1

According to the official documentation on this instance,

Scheduling an event to occur within 10 minutes of an existing event with the same action hook will be ignored unless you pass unique $args values for each scheduled event. which you have stated tht you did but maybe a double check will help.

It is dependent on when a user visits the site so the action will trigger when someone visits your WordPress site if the scheduled time has passed.

Documentation also says you could use wp_next_scheduled() to prevent duplicate events and use wp_schedule_event() to schedule a recurring event.

The schedule might return true in certain instances where it run but was ignored. so it did run but it was ignored.

I would suggest a detailed log of everything that is sent and received so you can see for yourself if what is occuring is same as what you are confident on.

here are a few links with similar issues and documentation you could look at.

I hope this helps. if not, lets figure it out together.

Alicealicea answered 5/3, 2020 at 7:54 Comment(0)
M
1

In my case this exact issue occurred when also Woocommerce's action scheduler was running. Action Scheduler is a cron task manager that ships with Woocommerce, but also other plugins like for instance wp-mail-smtp.

I had exactly the same issue and couldn't figure out what was wrong. I've tried to debug the Wordpress code, and came to the conclusion that when a task was scheduled (meaning, the moment it was added to the scheduled tasks) within 10 second of each whole minute, it just got removed straight away. It seemed some sort of racing condition where the action scheduler just popped it of the stack without the normal wp cron being able to execute it, because the task was already gone.

I need to also say, that I've setup crontab calling wp-cron.php every minute on the minute (instead of the 'fake cron' of Wordpress).

When I replaced wp_schedule_single_event with the as_enqueue_async_action function of the Action Scheduler, no tasks were dropped anymore.

I think an alternative is deinstalling anything that uses Action Scheduler, but I haven't tried that.

Mcwherter answered 27/7, 2021 at 7:42 Comment(0)
B
0

From Wordpress Document:

WP-Cron works by checking, on every page load, a list of scheduled tasks to see what needs to be run. Any tasks due to run will be called during that page load.

WP-Cron does not run constantly as the system cron does; it is only triggered on page load.

Scheduling errors could occur if you schedule a task for 2:00PM and no page loads occur until 5:00PM.

I think your cron event may be missed because there is no page loads occur the scheduled time.

Here is a solution for your problem: Hooking WP-Cron Into the System Task Scheduler

As previously mentioned, WP-Cron does not run continuously, which can be an issue if there are critical tasks that must run on time. There is an easy solution for this. Simply set up your system’s task scheduler to run on the intervals you desire (or at the specific time needed). The easiest solution is to use a tool to make a web request to the wp-cron.php file...

Batik answered 24/7, 2021 at 11:2 Comment(0)
D
-1

You are using cron from Wordpress but some plugins disable or prevent CRON from working. My recommendation in this case is either you create this schedule through the Server Cron or you install a plugin to reaffirm your schedule.

I had the same problem it was even a little difficult to find ... And as you will see it doesn't have a current update, but for me it works. https://wordpress.org/plugins/wp-crontrol & https://br.wordpress.org/plugins/advanced-cron-manager/

you can identify which Cron you want to edit and thus have more precision in your edition. There are other plugins that can and should be related to this one. you mentioned about cron's schedule. That's why I indicated this one. So, you can know the Chrome configuration on the calendar. WP Cron you can edit your Cron schedule

Dandelion answered 1/3, 2020 at 4:54 Comment(2)
then use this plugin that I put as a reference and you won't have any more problemsDandelion
The plugins are for viewing the cron job activity. How could they help solve my problem with the code? Also, I already have the latter one installed.Occlude

© 2022 - 2025 — McMap. All rights reserved.