Last active
September 21, 2024 15:47
-
-
Save devinsays/4bb6f8804afe88a9435ac5635fa3dcfd to your computer and use it in GitHub Desktop.
Modifications to Action Scheduler in order to run higher volumes of actions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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