[wp-trac] [WordPress Trac] #57924: Cron fires twice

WordPress Trac noreply at wordpress.org
Mon Mar 20 14:47:25 UTC 2023


#57924: Cron fires twice
-------------------------------------------+------------------------------
 Reporter:  j3gaming                       |       Owner:  j3gaming
     Type:  defect (bug)                   |      Status:  assigned
 Priority:  normal                         |   Milestone:  Awaiting Review
Component:  Cron API                       |     Version:  6.1.1
 Severity:  normal                         |  Resolution:
 Keywords:  changes-requested 2nd-opinion  |     Focuses:
-------------------------------------------+------------------------------

Comment (by j3gaming):

 Replying to [comment:15 j3gaming]:
 > **My fix. wp-config.php**
 >
 >
 > {{{
 > // The cron lock: a unix timestamp from when the cron was spawned.
 > $doing_cron_transient = get_transient( 'doing_cron' );
 >
 > // Use global $doing_wp_cron lock, otherwise use the GET lock. If no
 lock, try to grab a new lock.
 > if ( empty( $doing_wp_cron ) ) {
 >       if ( empty( $_GET['doing_wp_cron'] ) ) {
 >               // Called from external script/job. Try setting a lock.
 >               if ( $doing_cron_transient && ( $doing_cron_transient +
 WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) {
 >                       return;
 >               }
 >               $doing_wp_cron        = sprintf( '%.22F', microtime( true
 ) );
 >               $doing_cron_transient = $doing_wp_cron;
 >               set_transient( 'doing_cron', $doing_wp_cron );
 >       } else {
 >               $doing_wp_cron = $_GET['doing_wp_cron'];
 >       }
 > }
 >
 > // Wait x seconds before checking the database.
 > sleep(2); // Could be WP_CONFIG configurable. Default could be 0, anyone
 complaining about crons running could set this to 1 or more.
 >
 > // Grab the true database value after possible racing conditions.
 > $doing_cron_transient = get_transient( 'doing_cron' );
 >
 > /*
 >  * The cron lock (a unix timestamp set when the cron was spawned),
 >  * must match $doing_wp_cron (the "key").
 >  */
 > if ( $doing_cron_transient !== $doing_wp_cron ) {
 >       return;
 > }
 > }}}


 Needed to change the fix slightly. This should work.
 Also maybe consider moving the check/return currently at the end of the
 loop, to the start of the loop.

 {{{
 // The cron lock: a unix timestamp from when the cron was spawned.
 $doing_cron_transient = get_transient( 'doing_cron' );

 // Use global $doing_wp_cron lock, otherwise use the GET lock. If no lock,
 try to grab a new lock.
 if ( empty( $doing_wp_cron ) ) {
         if ( empty( $_GET['doing_wp_cron'] ) ) {
                 // Called from external script/job. Try setting a lock.
                 if ( $doing_cron_transient && ( $doing_cron_transient +
 WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) {
                         return;
                 }
                 $doing_wp_cron        = sprintf( '%.22F', microtime( true
 ) );
                 $doing_cron_transient = $doing_wp_cron;
                 set_transient( 'doing_cron', $doing_wp_cron );
         } else {
                 $doing_wp_cron = $_GET['doing_wp_cron'];
         }
 }

 // Wait x seconds before checking the database.
 sleep(2); // Could be WP_CONFIG configurable. Default could be 0, anyone
 complaining about crons running could set this to 1 or more.

 // Grab the true database value after possible racing conditions.
 $doing_cron_transient = get_transient( 'doing_cron' );

 /*
  * The cron lock (a unix timestamp set when the cron was spawned),
  * must match $doing_wp_cron (the "key").
  */
 if ( _get_cron_lock() !== $doing_wp_cron ) {
         return;
 }
 }}}

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


More information about the wp-trac mailing list