run_cleanup(); $this->add_hooks(); // Check to make sure there aren't too many concurrent processes running. $claim_count = $this->store->get_claim_count(); $too_many = $claim_count >= $this->get_allowed_concurrent_batches(); if ( $too_many ) { if ( $force ) { WP_CLI::warning( __( 'There are too many concurrent batches, but the run is forced to continue.', 'woocommerce' ) ); } else { WP_CLI::error( __( 'There are too many concurrent batches.', 'woocommerce' ) ); } } // Stake a claim and store it. $this->claim = $this->store->stake_claim( $batch_size, null, $hooks, $group ); $this->monitor->attach( $this->claim ); $this->actions = $this->claim->get_actions(); return count( $this->actions ); } /** * Add our hooks to the appropriate actions. * * @author Jeremy Pry */ protected function add_hooks() { add_action( 'action_scheduler_before_execute', array( $this, 'before_execute' ) ); add_action( 'action_scheduler_after_execute', array( $this, 'after_execute' ), 10, 2 ); add_action( 'action_scheduler_failed_execution', array( $this, 'action_failed' ), 10, 2 ); } /** * Set up the WP CLI progress bar. * * @author Jeremy Pry */ protected function setup_progress_bar() { $count = count( $this->actions ); $this->progress_bar = \WP_CLI\Utils\make_progress_bar( sprintf( _n( 'Running %d action', 'Running %d actions', $count, 'woocommerce' ), number_format_i18n( $count ) ), $count ); } /** * Process actions in the queue. * * @author Jeremy Pry * @return int The number of actions processed. */ public function run() { do_action( 'action_scheduler_before_process_queue' ); $this->setup_progress_bar(); foreach ( $this->actions as $action_id ) { // Error if we lost the claim. if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $this->claim->get_id() ) ) ) { WP_CLI::warning( __( 'The claim has been lost. Aborting current batch.', 'woocommerce' ) ); break; } $this->process_action( $action_id ); $this->progress_bar->tick(); $this->maybe_stop_the_insanity(); } $completed = $this->progress_bar->current(); $this->progress_bar->finish(); $this->store->release_claim( $this->claim ); do_action( 'action_scheduler_after_process_queue' ); return $completed; } /** * Handle WP CLI message when the action is starting. * * @author Jeremy Pry * * @param $action_id */ public function before_execute( $action_id ) { /* translators: %s refers to the action ID */ WP_CLI::log( sprintf( __( 'Started processing action %s', 'woocommerce' ), $action_id ) ); } /** * Handle WP CLI message when the action has completed. * * @author Jeremy Pry * * @param int $action_id * @param null|ActionScheduler_Action $action The instance of the action. Default to null for backward compatibility. */ public function after_execute( $action_id, $action = null ) { // backward compatibility if ( null === $action ) { $action = $this->store->fetch_action( $action_id ); } /* translators: %s refers to the action ID */ WP_CLI::log( sprintf( __( 'Completed processing action %s with hook: %s', 'woocommerce' ), $action_id, $action->get_hook() ) ); } /** * Handle WP CLI message when the action has failed. * * @author Jeremy Pry * * @param int $action_id * @param Exception $exception * @throws \WP_CLI\ExitException With failure message. */ public function action_failed( $action_id, $exception ) { WP_CLI::error( /* translators: %1$s refers to the action ID, %2$s refers to the Exception message */ sprintf( __( 'Error processing action %1$s: %2$s', 'woocommerce' ), $action_id, $exception->getMessage() ), false ); } /** * Sleep and help avoid hitting memory limit * * @param int $sleep_time Amount of seconds to sleep */ protected function stop_the_insanity( $sleep_time = 0 ) { if ( 0 < $sleep_time ) { /* translators: 1: sleep time 2: time unit */ WP_CLI::warning( sprintf( __( 'Stopped the insanity for %$1d %$2s', 'woocommerce' ), $sleep_time, _n( 'second', 'seconds', $sleep_time, 'woocommerce' ) ) ); sleep( $sleep_time ); } WP_CLI::warning( __( 'Attempting to reduce used memory...', 'woocommerce' ) ); /** * @var $wpdb \wpdb * @var $wp_object_cache \WP_Object_Cache */ global $wpdb, $wp_object_cache; $wpdb->queries = array(); if ( ! is_object( $wp_object_cache ) ) { return; } $wp_object_cache->group_ops = array(); $wp_object_cache->stats = array(); $wp_object_cache->memcache_debug = array(); $wp_object_cache->cache = array(); if ( is_callable( array( $wp_object_cache, '__remoteset' ) ) ) { call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important } } /** * Maybe trigger the stop_the_insanity() method to free up memory. */ protected function maybe_stop_the_insanity() { // The value returned by progress_bar->current() might be padded. Remove padding, and convert to int. $current_iteration = intval( trim( $this->progress_bar->current() ) ); if ( 0 === $current_iteration % 50 ) { $this->stop_the_insanity(); } } }