Commit 12fc3987 authored by Erick Hitter's avatar Erick Hitter Committed by GitHub
Browse files

Merge pull request #11 from Automattic/update/event-cpt-interaction

Update CPT entries directly, rather than through Core's cron functions 
parents 64a1da2f 9d7d8dc5
......@@ -186,22 +186,7 @@ class Cron_Options_CPT extends Singleton {
$job_exists = $this->job_exists( $event['timestamp'], $event['action'], $event['instance'] );
if ( ! $job_exists ) {
// Build minimum information needed to create a post
$job_post = array(
'post_title' => $this->event_title( $event['timestamp'], $event['action'], $event['instance'] ),
'post_name' => $this->event_name( $event['timestamp'], $event['action'], $event['instance'] ),
'post_content_filtered' => maybe_serialize( array(
'action' => $event['action'],
'instance' => $event['instance'],
'args' => $event['args'],
) ),
'post_date' => date( 'Y-m-d H:i:s', $event['timestamp'] ),
'post_date_gmt' => date( 'Y-m-d H:i:s', $event['timestamp'] ),
'post_type' => self::POST_TYPE,
'post_status' => self::POST_STATUS_PENDING,
);
$this->create_job( $job_post );
$this->create_job( $event['timestamp'], $event['action'], $event['args'] );
}
}
}
......@@ -253,12 +238,29 @@ class Cron_Options_CPT extends Singleton {
*
* `wp_insert_post()` can't be called as early as we need, in part because of the capabilities checks Core performs
*/
private function create_job( $job_post ) {
public function create_job( $timestamp, $action, $args ) {
// Limit how many events to insert at once
if ( ! Lock::check_lock( self::LOCK, 5 ) ) {
return false;
}
// Build minimum information needed to create a post
$instance = md5( serialize( $args['args'] ) );
$job_post = array(
'post_title' => $this->event_title( $timestamp, $action, $instance ),
'post_name' => $this->event_name( $timestamp, $action, $instance ),
'post_content_filtered' => maybe_serialize( array(
'action' => $action,
'instance' => $instance,
'args' => $args,
) ),
'post_date' => date( 'Y-m-d H:i:s', $timestamp ),
'post_date_gmt' => date( 'Y-m-d H:i:s', $timestamp ),
'post_type' => self::POST_TYPE,
'post_status' => self::POST_STATUS_PENDING,
);
// If called before `init`, we need to insert directly because post types aren't registered earlier
if ( did_action( 'init' ) ) {
wp_insert_post( $job_post );
......@@ -318,7 +320,7 @@ class Cron_Options_CPT extends Singleton {
*
* @return bool
*/
private function mark_job_completed( $timestamp, $action, $instance ) {
public function mark_job_completed( $timestamp, $action, $instance ) {
$job_post_id = $this->job_exists( $timestamp, $action, $instance, true );
if ( ! $job_post_id ) {
......
......@@ -135,20 +135,14 @@ class Events extends Singleton {
return new \WP_Error( 'no-free-threads', sprintf( __( 'No resources available to run the job with action action `%1$s` and arguments `%2$s`.', 'automattic-cron-control' ), $event['action'], maybe_serialize( $event['args'] ) ), array( 'status' => 429, ) );
}
// Mark the event completed, and reschedule if desired
$this->update_event_record( $event );
// Prepare environment to run job
ignore_user_abort( true );
set_time_limit( JOB_TIMEOUT_IN_MINUTES * MINUTE_IN_SECONDS );
define( 'DOING_CRON', true );
// Remove the event, and reschedule if desired
// Follows pattern Core uses in wp-cron.php
if ( false !== $event['schedule'] ) {
$reschedule_args = array( $event['timestamp'], $event['schedule'], $event['action'], $event['args'] );
call_user_func_array( 'wp_reschedule_event', $reschedule_args );
}
wp_unschedule_event( $event['timestamp'], $event['action'], $event['args'] );
// Run the event
do_action_ref_array( $event['action'], $event['args'] );
......@@ -164,6 +158,51 @@ class Events extends Singleton {
'message' => sprintf( __( 'Job with action `%1$s` and arguments `%2$s` completed in %3$d seconds.', 'automattic-cron-control' ), $event['action'], maybe_serialize( $event['args'] ), $time_end - $time_start ),
);
}
/**
* Mark an event completed, and reschedule when requested
*/
private function update_event_record( $event ) {
if ( false !== $event['schedule'] ) {
// Re-implements much of the logic from `wp_reschedule_event()`
$schedules = wp_get_schedules();
$interval = 0;
// First, we try to get it from the schedule
if ( isset( $schedules[ $event['schedule'] ] ) ) {
$interval = $schedules[ $event['schedule'] ]['interval'];
}
// Now we try to get it from the saved interval, in case the schedule disappears
if ( 0 == $interval ) {
$interval = $event['interval'];
}
// If we have an interval, create a new event entry
if ( 0 != $interval ) {
// Determine new timestamp, according to how `wp_reschedule_event()` does
$now = time();
$new_timestamp = $event['timestamp'];
if ( $new_timestamp >= $now ) {
$new_timestamp = $now + $interval;
} else {
$new_timestamp = $now + ( $interval - ( ( $now - $new_timestamp ) % $interval ) );
}
// Build the expected arguments format
$event_args = array(
'schedule' => $event['schedule'],
'args' => $event['args'],
'interval' => $interval,
);
Cron_Options_CPT::instance()->create_job( $new_timestamp, $event['action'], $event_args );
}
}
Cron_Options_CPT::instance()->mark_job_completed( $event['timestamp'], $event['action'], $event['instance'] );
}
}
Events::instance();
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment