PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.6.4
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.6.4
4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / vendor / woocommerce / action-scheduler / classes / ActionScheduler_QueueRunner.php
surecart / vendor / woocommerce / action-scheduler / classes Last commit date
WP_CLI 3 years ago abstracts 1 year ago actions 3 years ago data-stores 1 year ago migration 1 year ago schedules 3 years ago schema 2 years ago ActionScheduler_ActionClaim.php 3 years ago ActionScheduler_ActionFactory.php 1 year ago ActionScheduler_AdminView.php 1 year ago ActionScheduler_AsyncRequest_QueueRunner.php 3 years ago ActionScheduler_Compatibility.php 3 years ago ActionScheduler_DataController.php 3 years ago ActionScheduler_DateTime.php 3 years ago ActionScheduler_Exception.php 3 years ago ActionScheduler_FatalErrorMonitor.php 3 years ago ActionScheduler_InvalidActionException.php 3 years ago ActionScheduler_ListTable.php 1 year ago ActionScheduler_LogEntry.php 3 years ago ActionScheduler_NullLogEntry.php 3 years ago ActionScheduler_OptionLock.php 2 years ago ActionScheduler_QueueCleaner.php 3 years ago ActionScheduler_QueueRunner.php 2 years ago ActionScheduler_Versions.php 3 years ago ActionScheduler_WPCommentCleaner.php 3 years ago ActionScheduler_wcSystemStatus.php 3 years ago
ActionScheduler_QueueRunner.php
230 lines
1 <?php
2
3 /**
4 * Class ActionScheduler_QueueRunner
5 */
6 class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
7 const WP_CRON_HOOK = 'action_scheduler_run_queue';
8
9 const WP_CRON_SCHEDULE = 'every_minute';
10
11 /** @var ActionScheduler_AsyncRequest_QueueRunner */
12 protected $async_request;
13
14 /** @var ActionScheduler_QueueRunner */
15 private static $runner = null;
16
17 /** @var int */
18 private $processed_actions_count = 0;
19
20 /**
21 * @return ActionScheduler_QueueRunner
22 * @codeCoverageIgnore
23 */
24 public static function instance() {
25 if ( empty(self::$runner) ) {
26 $class = apply_filters('action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner');
27 self::$runner = new $class();
28 }
29 return self::$runner;
30 }
31
32 /**
33 * ActionScheduler_QueueRunner constructor.
34 *
35 * @param ActionScheduler_Store $store
36 * @param ActionScheduler_FatalErrorMonitor $monitor
37 * @param ActionScheduler_QueueCleaner $cleaner
38 */
39 public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) {
40 parent::__construct( $store, $monitor, $cleaner );
41
42 if ( is_null( $async_request ) ) {
43 $async_request = new ActionScheduler_AsyncRequest_QueueRunner( $this->store );
44 }
45
46 $this->async_request = $async_request;
47 }
48
49 /**
50 * @codeCoverageIgnore
51 */
52 public function init() {
53
54 add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) );
55
56 // Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param
57 $next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK );
58 if ( $next_timestamp ) {
59 wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK );
60 }
61
62 $cron_context = array( 'WP Cron' );
63
64 if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) {
65 $schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE );
66 wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context );
67 }
68
69 add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) );
70 $this->hook_dispatch_async_request();
71 }
72
73 /**
74 * Hook check for dispatching an async request.
75 */
76 public function hook_dispatch_async_request() {
77 add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) );
78 }
79
80 /**
81 * Unhook check for dispatching an async request.
82 */
83 public function unhook_dispatch_async_request() {
84 remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) );
85 }
86
87 /**
88 * Check if we should dispatch an async request to process actions.
89 *
90 * This method is attached to 'shutdown', so is called frequently. To avoid slowing down
91 * the site, it mitigates the work performed in each request by:
92 * 1. checking if it's in the admin context and then
93 * 2. haven't run on the 'shutdown' hook within the lock time (60 seconds by default)
94 * 3. haven't exceeded the number of allowed batches.
95 *
96 * The order of these checks is important, because they run from a check on a value:
97 * 1. in memory - is_admin() maps to $GLOBALS or the WP_ADMIN constant
98 * 2. in memory - transients use autoloaded options by default
99 * 3. from a database query - has_maximum_concurrent_batches() run the query
100 * $this->store->get_claim_count() to find the current number of claims in the DB.
101 *
102 * If all of these conditions are met, then we request an async runner check whether it
103 * should dispatch a request to process pending actions.
104 */
105 public function maybe_dispatch_async_request() {
106 // Only start an async queue at most once every 60 seconds.
107 if (
108 is_admin()
109 && ! ActionScheduler::lock()->is_locked( 'async-request-runner' )
110 && ActionScheduler::lock()->set( 'async-request-runner' )
111 ) {
112 $this->async_request->maybe_dispatch();
113 }
114 }
115
116 /**
117 * Process actions in the queue. Attached to self::WP_CRON_HOOK i.e. 'action_scheduler_run_queue'
118 *
119 * The $context param of this method defaults to 'WP Cron', because prior to Action Scheduler 3.0.0
120 * that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context
121 * passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK,
122 * should set a context as the first parameter. For an example of this, refer to the code seen in
123 * @see ActionScheduler_AsyncRequest_QueueRunner::handle()
124 *
125 * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
126 * Generally, this should be capitalised and not localised as it's a proper noun.
127 * @return int The number of actions processed.
128 */
129 public function run( $context = 'WP Cron' ) {
130 ActionScheduler_Compatibility::raise_memory_limit();
131 ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() );
132 do_action( 'action_scheduler_before_process_queue' );
133 $this->run_cleanup();
134
135 $this->processed_actions_count = 0;
136 if ( false === $this->has_maximum_concurrent_batches() ) {
137 $batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 );
138 do {
139 $processed_actions_in_batch = $this->do_batch( $batch_size, $context );
140 $this->processed_actions_count += $processed_actions_in_batch;
141 } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $this->processed_actions_count ) ); // keep going until we run out of actions, time, or memory
142 }
143
144 do_action( 'action_scheduler_after_process_queue' );
145 return $this->processed_actions_count;
146 }
147
148 /**
149 * Process a batch of actions pending in the queue.
150 *
151 * Actions are processed by claiming a set of pending actions then processing each one until either the batch
152 * size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded().
153 *
154 * @param int $size The maximum number of actions to process in the batch.
155 * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
156 * Generally, this should be capitalised and not localised as it's a proper noun.
157 * @return int The number of actions processed.
158 */
159 protected function do_batch( $size = 100, $context = '' ) {
160 $claim = $this->store->stake_claim($size);
161 $this->monitor->attach($claim);
162 $processed_actions = 0;
163
164 foreach ( $claim->get_actions() as $action_id ) {
165 // bail if we lost the claim
166 if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) {
167 break;
168 }
169 $this->process_action( $action_id, $context );
170 $processed_actions++;
171
172 if ( $this->batch_limits_exceeded( $processed_actions + $this->processed_actions_count ) ) {
173 break;
174 }
175 }
176 $this->store->release_claim($claim);
177 $this->monitor->detach();
178 $this->clear_caches();
179 return $processed_actions;
180 }
181
182 /**
183 * Flush the cache if possible (intended for use after a batch of actions has been processed).
184 *
185 * This is useful because running large batches can eat up memory and because invalid data can accrue in the
186 * runtime cache, which may lead to unexpected results.
187 */
188 protected function clear_caches() {
189 /*
190 * Calling wp_cache_flush_runtime() lets us clear the runtime cache without invalidating the external object
191 * cache, so we will always prefer this method (as compared to calling wp_cache_flush()) when it is available.
192 *
193 * However, this function was only introduced in WordPress 6.0. Additionally, the preferred way of detecting if
194 * it is supported changed in WordPress 6.1 so we use two different methods to decide if we should utilize it.
195 */
196 $flushing_runtime_cache_explicitly_supported = function_exists( 'wp_cache_supports' ) && wp_cache_supports( 'flush_runtime' );
197 $flushing_runtime_cache_implicitly_supported = ! function_exists( 'wp_cache_supports' ) && function_exists( 'wp_cache_flush_runtime' );
198
199 if ( $flushing_runtime_cache_explicitly_supported || $flushing_runtime_cache_implicitly_supported ) {
200 wp_cache_flush_runtime();
201 } elseif (
202 ! wp_using_ext_object_cache()
203 /**
204 * When an external object cache is in use, and when wp_cache_flush_runtime() is not available, then
205 * normally the cache will not be flushed after processing a batch of actions (to avoid a performance
206 * penalty for other processes).
207 *
208 * This filter makes it possible to override this behavior and always flush the cache, even if an external
209 * object cache is in use.
210 *
211 * @since 1.0
212 *
213 * @param bool $flush_cache If the cache should be flushed.
214 */
215 || apply_filters( 'action_scheduler_queue_runner_flush_cache', false )
216 ) {
217 wp_cache_flush();
218 }
219 }
220
221 public function add_wp_cron_schedule( $schedules ) {
222 $schedules['every_minute'] = array(
223 'interval' => 60, // in seconds
224 'display' => __( 'Every minute', 'action-scheduler' ),
225 );
226
227 return $schedules;
228 }
229 }
230