AbstractASQueue.php
8.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
<?php
declare( strict_types=1 );
namespace WP_Rocket\Engine\Common\Queue;
use ActionScheduler_Store;
use Exception;
use WP_Rocket\Logger\Logger;
abstract class AbstractASQueue implements QueueInterface {
/**
* Queue shared Group.
*
* @var string
*/
protected $group = 'rocket';
/**
* Enqueue an action to run one time, as soon as possible
*
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @return int The action ID.
*/
public function add_async( $hook, $args = [] ) {
try {
return as_enqueue_async_action( $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return 0;
}
}
/**
* Schedule an action to run once at some time in the future
*
* @param int $timestamp When the job will run.
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @return int The action ID.
*/
public function schedule_single( $timestamp, $hook, $args = [] ) {
try {
return as_schedule_single_action( $timestamp, $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return 0;
}
}
/**
* Schedule a recurring action
*
* @param int $timestamp When the first instance of the job will run.
* @param int $interval_in_seconds How long to wait between runs.
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @return int The action ID.
*/
public function schedule_recurring( $timestamp, $interval_in_seconds, $hook, $args = [] ) {
if ( $this->is_scheduled( $hook, $args ) ) {
// TODO: When v3.3.0 from Action Scheduler is commonly used use the array notation for status to reduce search queries to one.
$pending_actions = $this->search(
[
'hook' => $hook,
'status' => ActionScheduler_Store::STATUS_PENDING,
],
'ids'
);
if ( 1 < count( $pending_actions ) ) {
$this->cancel_all( $hook, $args );
return '';
}
$running_actions = $this->search(
[
'hook' => $hook,
'status' => ActionScheduler_Store::STATUS_RUNNING,
],
'ids'
);
if ( 1 === count( $pending_actions ) + count( $running_actions ) ) {
return '';
}
$this->cancel_all( $hook, $args );
}
try {
return as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return 0;
}
}
/**
* Checks if the hook is scheduled.
*
* @param string $hook The hook to check.
* @param array $args Passed arguments.
*
* @return bool
*/
public function is_scheduled( $hook, $args = [] ) {
if ( ! function_exists( 'as_has_scheduled_action' ) ) {
return ! is_null( $this->get_next( $hook, $args ) );
}
try {
return as_has_scheduled_action( $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return false;
}
}
/**
* Schedule an action that recurs on a cron-like schedule.
*
* @param int $timestamp The schedule will start on or after this time.
* @param string $cron_schedule A cron-link schedule string.
* @see http://en.wikipedia.org/wiki/Cron
* * * * * * *
* ┬ ┬ ┬ ┬ ┬ ┬
* | | | | | |
* | | | | | + year [optional]
* | | | | +----- day of week (0 - 7) (Sunday=0 or 7)
* | | | +---------- month (1 - 12)
* | | +--------------- day of month (1 - 31)
* | +-------------------- hour (0 - 23)
* +------------------------- min (0 - 59)
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @return int The action ID
*/
public function schedule_cron( $timestamp, $cron_schedule, $hook, $args = [] ) {
if ( $this->is_scheduled( $hook, $args ) ) {
return '';
}
try {
return as_schedule_cron_action( $timestamp, $cron_schedule, $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return 0;
}
}
/**
* Dequeue the next scheduled instance of an action with a matching hook (and optionally matching args and group).
*
* Any recurring actions with a matching hook should also be cancelled, not just the next scheduled action.
*
* While technically only the next instance of a recurring or cron action is unscheduled by this method, that will also
* prevent all future instances of that recurring or cron action from being run. Recurring and cron actions are scheduled
* in a sequence instead of all being scheduled at once. Each successive occurrence of a recurring action is scheduled
* only after the former action is run. As the next instance is never run, because it's unscheduled by this function,
* then the following instance will never be scheduled (or exist), which is effectively the same as being unscheduled
* by this method also.
*
* @param string $hook The hook that the job will trigger.
* @param array $args Args that would have been passed to the job.
*/
public function cancel( $hook, $args = [] ) {
try {
as_unschedule_action( $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
}
}
/**
* Dequeue all actions with a matching hook (and optionally matching args and group) so no matching actions are ever run.
*
* @param string $hook The hook that the job will trigger.
* @param array $args Args that would have been passed to the job.
*/
public function cancel_all( $hook, $args = [] ) {
try {
as_unschedule_all_actions( $hook, $args, $this->group );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
}
}
/**
* Get the date and time for the next scheduled occurence of an action with a given hook
* (an optionally that matches certain args and group), if any.
*
* @param string $hook The hook that the job will trigger.
* @param array $args Filter to a hook with matching args that will be passed to the job when it runs.
* @return int|null The date and time for the next occurrence, or null if there is no pending, scheduled action for the given hook.
*/
public function get_next( $hook, $args = null ) {
try {
$next_timestamp = as_next_scheduled_action( $hook, $args, $this->group );
if ( is_numeric( $next_timestamp ) ) {
return $next_timestamp;
}
return null;
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return null;
}
}
/**
* Find scheduled actions
*
* @param array $args Possible arguments, with their default values:
* 'hook' => '' - the name of the action that will be triggered
* 'args' => null - the args array that will be passed with the action
* 'date' => null - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
* 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='
* 'modified' => null - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
* 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='
* 'group' => '' - the group the action belongs to
* 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING
* 'claimed' => null - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID
* 'per_page' => 5 - Number of results to return
* 'offset' => 0
* 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date'
* 'order' => 'ASC'.
*
* @param string $return_format OBJECT, ARRAY_A, or ids.
* @return array
*/
public function search( $args = [], $return_format = OBJECT ) {
try {
return as_get_scheduled_actions( $args, $return_format );
} catch ( Exception $exception ) {
Logger::error( $exception->getMessage(), [ 'Action Scheduler Queue' ] );
return [];
}
}
}