[wp-trac] [WordPress Trac] #42866: WordPress Community Scheduler Interval Bug

WordPress Trac noreply at wordpress.org
Mon Dec 11 07:26:14 UTC 2017


#42866: WordPress Community Scheduler Interval Bug
--------------------------+-----------------------------
 Reporter:  mrperl        |       Owner:
     Type:  defect (bug)  |      Status:  closed
 Priority:  normal        |   Milestone:
Component:  Cron API      |     Version:  4.4.2
 Severity:  normal        |  Resolution:  worksforme
 Keywords:                |     Focuses:  administration
--------------------------+-----------------------------
Changes (by dd32):

 * status:  new => closed
 * resolution:   => worksforme
 * milestone:  Awaiting Review =>


Comment:

 Hi @mrperl and welcome to Trac.

 It appears that cron is working as expected here to me - although I can
 see why you'd see differently.

 The WordPress cron is a best-effort scheduler, and not a guaranteed
 scheduler, it runs based on non-cached visits to WordPress in most
 situations.

 Here's an example of what I think is happening here:
  - I schedule a job to run every 15 minutes, starting at 00:00:00.
  - At 00:00:01 a request hits my WordPress site, it see's that I've got a
 cron task that needs running. WordPress spawns a process to run that job.
  - At 00:00:02 the loopback HTTP request WordPress has made hits PHP and
 the cron task is run. The task takes 2 seconds to run. At 00:00:04
 WordPress notices that it's a recurring job, it schedules the job to run
 again - `$scheduled_time + $interval` = `00:15:00` - in 14m56s
  - A bunch of HTTP requests hit a caching plugin, WordPress never loads.
  - At 00:14:55 another request hits WordPress, no scheduled jobs need
 running.
  - A bunch of HTTP requests hit a caching plugin, WordPress never loads.
  - At 00:16:30 the next HTTP request hits WordPress, WordPress see's that
 a job should've run at `00:15:00`, it spawns cron via HTTP loopback. It's
 been 16m24s since the last cron ran.  ***Cron runs late***
  - At 00:16:32 the cron task runs, it takes 30s this time due to a slow
 network. At 00:17:02 the task has finished and WordPress schedules the
 task to run again - `$scheduled_time + $interval` = `00:30:00` - in 12m58s
  - A bunch of HTTP requests hit a caching plugin, WordPress never loads.
  - At 00:30:03 the next HTTP request hits WordPress, WordPress see's that
 a job should've run at `00:30:00`, it spawns cron via HTTP loopback. It's
 been 13m01s since the last cron ran. ***Cron runs "early"***
  - At 00:30:04 the cron task runs, it takes 1s. At 00:30:05 the task has
 finished and WordPress schedules the task to run again - `$scheduled_time
 + $interval` = `00:45:00` - in 14m:55s
 .. etc.

 In order to improve cron spawning, some people have been known to run a
 real cron task which hits `site.com/wp-cron.php` regularly - however this
 has the downside that it can cause cron tasks to double up (as it bypasses
 the WordPress cron locks).
 There also exist external cron daemons which can be used to run tasks more
 regularly, such as Cavalcade.

 But the best option here, is to simply expect that the cron task will
 never run on the exact schedule, it may run faster or slower depending on
 when cron tasks are scheduled and the amount of visitors to WordPress - If
 no-one visits WordPress, the cron jobs will never even run for example.
 It's also possible that the job may run multiple times if the job takes
 too long to finish, as WordPress may think the cron task failed to
 execute.

 If you wish for your cron tasks to run `at least 15 minutes after the time
 the last job finished` you may wish to consider not using a recurring cron
 task, and instead schedule a task to run in 15 minutes from now at the end
 of your job, for example:

 {{{
 add_action( "init", "job_setup" );
 function job_setup() {
   if ( ! wp_next_scheduled( 'my_job' ) ) {
     wp_schedule_single_event( "my_job", time() );
   }
 }

 add_action( "my_job_name", "job_callback" );
 function job_callback() {
   // do stuff that takes 1s ~ 15 minutes
   // ...
   // Schedule this to run again in 15+ minutes time that his job finished
 at
    wp_schedule_single_event( "my_job", time() + 15 * 60 * 60 );
 }
 }}}
 I'd recommend that you always check if the job is scheduled though and not
 just do it on activation, as the job may fail or PHP timeout and it never
 gets to the reschedule event.

 I'm marking this as `worksforme` as it seems like it's working as expected
 for me, I hope this reply has helped you understand what you're most
 likely seeing.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/42866#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list