Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bahiirwa/47b379e19dc6245e542dbfa607b503a4 to your computer and use it in GitHub Desktop.
Save bahiirwa/47b379e19dc6245e542dbfa607b503a4 to your computer and use it in GitHub Desktop.
Modifications to Action Scheduler in order to run higher volumes of actions.
<?php
/**
* High volume modifications to Action Scheduler.
*
* Adapted from https://github.com/woocommerce/action-scheduler-high-volume/
*
* Increase Action Scheduler batch size, concurrency, timeout period, and claim action query
* ORDER BY to process large queues of actions more quickly on servers with more server resources.
*
* @package UniversalYums\ActionScheduler
*/
namespace UniversalYums\ActionScheduler;
class ActionSchedulerHighVolume {
/**
* The single instance of the class.
*
* @var mixed
*/
protected static $instance;
/**
* Ensures only one instance of ActionSchedulerHighVolume is loaded or can be loaded.
*
* @return ActionSchedulerHighVolume - Main instance.
*/
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* ActionSchedulerHighVolume constructor.
*/
public function __construct() {
add_filter( 'action_scheduler_queue_runner_batch_size', [ $this, 'increase_queue_batch_size' ] );
add_filter( 'action_scheduler_queue_runner_concurrent_batches', [ $this, 'increase_concurrent_batches' ], 10000 );
add_filter( 'action_scheduler_timeout_period', [ $this, 'increase_timeout' ] );
add_filter( 'action_scheduler_failure_period', [ $this, 'increase_timeout' ] );
add_filter( 'action_scheduler_queue_runner_time_limit', [ $this, 'increase_time_limit' ] );
add_filter( 'action_scheduler_claim_actions_order_by', [ $this, 'remove_order_by_date' ] );
}
/**
* Action scheduler claims a batch of actions to process in each request. It keeps the batch
* fairly small (by default, 25) in order to prevent errors, like memory exhaustion.
*
* This method increases it so that more actions are processed in each queue, which speeds up the
* overall queue processing time due to latency in requests and the minimum 1 minute between each
* queue being processed.
*
* For more details, see: https://actionscheduler.org/perf/#increasing-batch-size
*
* @param int $batch_size
*/
public function increase_queue_batch_size( $batch_size ) {
return $batch_size * 2;
}
/**
* Action scheduler processes queues of actions in parallel to speed up the processing of large numbers
* If each queue takes a long time, this will result in multiple PHP processes being used to process actions,
* which can prevent PHP processes being available to serve requests from visitors. This is why it defaults to
* only 1 (as of Action Scheduler 3.4.0). However, on high volume sites, this can be increased to speed up the
* processing time for actions.
*
* Use with caution as doing this can take down your site completely depending on your PHP configuration.
*
* For more details, see: https://actionscheduler.org/perf/#increasing-concurrent-batches
*
* @param int $concurrent_batches
*/
public function increase_concurrent_batches( $concurrent_batches ) {
return 20;
}
/**
* Action scheduler reset actions claimed for more than 5 minutes (300 seconds).
* Because we're increasing the batch size, we also want to increase the amount of time
* given to queues before reseting claimed actions.
*
* @param int $timeout
*/
public function increase_timeout( $timeout ) {
return $timeout * 2;
}
/**
* Action Scheduler provides a default maximum of 30 seconds in which to process actions. Increase this to 120
* seconds for hosts like Pantheon which support such a long time limit, or if you know your PHP and Apache, Nginx
* or other web server configs support a longer time limit.
*
* Note, WP Engine only supports a maximum of 60 seconds - if using WP Engine, this will need to be decreased to 60.
*
* @param int $time_limit
*/
public function increase_time_limit( $time_limit ) {
return 60;
}
/**
* Action Scheduler by default marks actions claimed in the order:
* `ORDER BY attempts ASC, scheduled_date_gmt ASC, action_id ASC`.
* We can improve improve the performance of this query by modifying the ORDER BY clause
* to remove, for example, ordering by `scheduled_date_gmt`, which, according to the docs,
* "considerably improves the speed of execution of the query and reduces the probability of deadlocks."
*
* @see https://developer.woocommerce.com/2021/11/01/action-scheduler-3-4-0/
*
* @param string $order_clause
*/
public function remove_order_by_date( $order_clause ) {
return 'ORDER BY attempts ASC, action_id ASC';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment