@@ -8,33 +8,33 @@ discard block |
||
8 | 8 | * Creates custom tables for storing scheduled actions |
9 | 9 | */ |
10 | 10 | class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema { |
11 | - const ACTIONS_TABLE = 'actionscheduler_actions'; |
|
12 | - const CLAIMS_TABLE = 'actionscheduler_claims'; |
|
13 | - const GROUPS_TABLE = 'actionscheduler_groups'; |
|
11 | + const ACTIONS_TABLE = 'actionscheduler_actions'; |
|
12 | + const CLAIMS_TABLE = 'actionscheduler_claims'; |
|
13 | + const GROUPS_TABLE = 'actionscheduler_groups'; |
|
14 | 14 | |
15 | - /** |
|
16 | - * @var int Increment this value to trigger a schema update. |
|
17 | - */ |
|
18 | - protected $schema_version = 3; |
|
15 | + /** |
|
16 | + * @var int Increment this value to trigger a schema update. |
|
17 | + */ |
|
18 | + protected $schema_version = 3; |
|
19 | 19 | |
20 | - public function __construct() { |
|
21 | - $this->tables = [ |
|
22 | - self::ACTIONS_TABLE, |
|
23 | - self::CLAIMS_TABLE, |
|
24 | - self::GROUPS_TABLE, |
|
25 | - ]; |
|
26 | - } |
|
20 | + public function __construct() { |
|
21 | + $this->tables = [ |
|
22 | + self::ACTIONS_TABLE, |
|
23 | + self::CLAIMS_TABLE, |
|
24 | + self::GROUPS_TABLE, |
|
25 | + ]; |
|
26 | + } |
|
27 | 27 | |
28 | - protected function get_table_definition( $table ) { |
|
29 | - global $wpdb; |
|
30 | - $table_name = $wpdb->$table; |
|
31 | - $charset_collate = $wpdb->get_charset_collate(); |
|
32 | - $max_index_length = 191; // @see wp_get_db_schema() |
|
33 | - switch ( $table ) { |
|
28 | + protected function get_table_definition( $table ) { |
|
29 | + global $wpdb; |
|
30 | + $table_name = $wpdb->$table; |
|
31 | + $charset_collate = $wpdb->get_charset_collate(); |
|
32 | + $max_index_length = 191; // @see wp_get_db_schema() |
|
33 | + switch ( $table ) { |
|
34 | 34 | |
35 | - case self::ACTIONS_TABLE: |
|
35 | + case self::ACTIONS_TABLE: |
|
36 | 36 | |
37 | - return "CREATE TABLE {$table_name} ( |
|
37 | + return "CREATE TABLE {$table_name} ( |
|
38 | 38 | action_id bigint(20) unsigned NOT NULL auto_increment, |
39 | 39 | hook varchar(191) NOT NULL, |
40 | 40 | status varchar(20) NOT NULL, |
@@ -58,26 +58,26 @@ discard block |
||
58 | 58 | KEY claim_id (claim_id) |
59 | 59 | ) $charset_collate"; |
60 | 60 | |
61 | - case self::CLAIMS_TABLE: |
|
61 | + case self::CLAIMS_TABLE: |
|
62 | 62 | |
63 | - return "CREATE TABLE {$table_name} ( |
|
63 | + return "CREATE TABLE {$table_name} ( |
|
64 | 64 | claim_id bigint(20) unsigned NOT NULL auto_increment, |
65 | 65 | date_created_gmt datetime NOT NULL default '0000-00-00 00:00:00', |
66 | 66 | PRIMARY KEY (claim_id), |
67 | 67 | KEY date_created_gmt (date_created_gmt) |
68 | 68 | ) $charset_collate"; |
69 | 69 | |
70 | - case self::GROUPS_TABLE: |
|
70 | + case self::GROUPS_TABLE: |
|
71 | 71 | |
72 | - return "CREATE TABLE {$table_name} ( |
|
72 | + return "CREATE TABLE {$table_name} ( |
|
73 | 73 | group_id bigint(20) unsigned NOT NULL auto_increment, |
74 | 74 | slug varchar(255) NOT NULL, |
75 | 75 | PRIMARY KEY (group_id), |
76 | 76 | KEY slug (slug($max_index_length)) |
77 | 77 | ) $charset_collate"; |
78 | 78 | |
79 | - default: |
|
80 | - return ''; |
|
81 | - } |
|
82 | - } |
|
79 | + default: |
|
80 | + return ''; |
|
81 | + } |
|
82 | + } |
|
83 | 83 | } |
@@ -25,12 +25,12 @@ |
||
25 | 25 | ]; |
26 | 26 | } |
27 | 27 | |
28 | - protected function get_table_definition( $table ) { |
|
28 | + protected function get_table_definition($table) { |
|
29 | 29 | global $wpdb; |
30 | 30 | $table_name = $wpdb->$table; |
31 | 31 | $charset_collate = $wpdb->get_charset_collate(); |
32 | 32 | $max_index_length = 191; // @see wp_get_db_schema() |
33 | - switch ( $table ) { |
|
33 | + switch ($table) { |
|
34 | 34 | |
35 | 35 | case self::ACTIONS_TABLE: |
36 | 36 |
@@ -4,8 +4,8 @@ |
||
4 | 4 | * Class ActionScheduler_NullLogEntry |
5 | 5 | */ |
6 | 6 | class ActionScheduler_NullLogEntry extends ActionScheduler_LogEntry { |
7 | - public function __construct( $action_id = '', $message = '' ) { |
|
8 | - // nothing to see here |
|
9 | - } |
|
7 | + public function __construct( $action_id = '', $message = '' ) { |
|
8 | + // nothing to see here |
|
9 | + } |
|
10 | 10 | } |
11 | - |
|
12 | 11 | \ No newline at end of file |
12 | + |
|
13 | 13 | \ No newline at end of file |
@@ -4,7 +4,7 @@ |
||
4 | 4 | * Class ActionScheduler_NullLogEntry |
5 | 5 | */ |
6 | 6 | class ActionScheduler_NullLogEntry extends ActionScheduler_LogEntry { |
7 | - public function __construct( $action_id = '', $message = '' ) { |
|
7 | + public function __construct($action_id = '', $message = '') { |
|
8 | 8 | // nothing to see here |
9 | 9 | } |
10 | 10 | } |
@@ -5,151 +5,151 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_QueueCleaner { |
7 | 7 | |
8 | - /** @var int */ |
|
9 | - protected $batch_size; |
|
10 | - |
|
11 | - /** @var ActionScheduler_Store */ |
|
12 | - private $store = null; |
|
13 | - |
|
14 | - /** |
|
15 | - * 31 days in seconds. |
|
16 | - * |
|
17 | - * @var int |
|
18 | - */ |
|
19 | - private $month_in_seconds = 2678400; |
|
20 | - |
|
21 | - /** |
|
22 | - * ActionScheduler_QueueCleaner constructor. |
|
23 | - * |
|
24 | - * @param ActionScheduler_Store $store The store instance. |
|
25 | - * @param int $batch_size The batch size. |
|
26 | - */ |
|
27 | - public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) { |
|
28 | - $this->store = $store ? $store : ActionScheduler_Store::instance(); |
|
29 | - $this->batch_size = $batch_size; |
|
30 | - } |
|
31 | - |
|
32 | - public function delete_old_actions() { |
|
33 | - $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds ); |
|
34 | - $cutoff = as_get_datetime_object($lifespan.' seconds ago'); |
|
35 | - |
|
36 | - $statuses_to_purge = array( |
|
37 | - ActionScheduler_Store::STATUS_COMPLETE, |
|
38 | - ActionScheduler_Store::STATUS_CANCELED, |
|
39 | - ); |
|
40 | - |
|
41 | - foreach ( $statuses_to_purge as $status ) { |
|
42 | - $actions_to_delete = $this->store->query_actions( array( |
|
43 | - 'status' => $status, |
|
44 | - 'modified' => $cutoff, |
|
45 | - 'modified_compare' => '<=', |
|
46 | - 'per_page' => $this->get_batch_size(), |
|
47 | - ) ); |
|
48 | - |
|
49 | - foreach ( $actions_to_delete as $action_id ) { |
|
50 | - try { |
|
51 | - $this->store->delete_action( $action_id ); |
|
52 | - } catch ( Exception $e ) { |
|
53 | - |
|
54 | - /** |
|
55 | - * Notify 3rd party code of exceptions when deleting a completed action older than the retention period |
|
56 | - * |
|
57 | - * This hook provides a way for 3rd party code to log or otherwise handle exceptions relating to their |
|
58 | - * actions. |
|
59 | - * |
|
60 | - * @since 2.0.0 |
|
61 | - * |
|
62 | - * @param int $action_id The scheduled actions ID in the data store |
|
63 | - * @param Exception $e The exception thrown when attempting to delete the action from the data store |
|
64 | - * @param int $lifespan The retention period, in seconds, for old actions |
|
65 | - * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch |
|
66 | - */ |
|
67 | - do_action( 'action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count( $actions_to_delete ) ); |
|
68 | - } |
|
69 | - } |
|
70 | - } |
|
71 | - } |
|
72 | - |
|
73 | - /** |
|
74 | - * Unclaim pending actions that have not been run within a given time limit. |
|
75 | - * |
|
76 | - * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
77 | - * as a parameter is 10x the time limit used for queue processing. |
|
78 | - * |
|
79 | - * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes). |
|
80 | - */ |
|
81 | - public function reset_timeouts( $time_limit = 300 ) { |
|
82 | - $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit ); |
|
83 | - if ( $timeout < 0 ) { |
|
84 | - return; |
|
85 | - } |
|
86 | - $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
87 | - $actions_to_reset = $this->store->query_actions( array( |
|
88 | - 'status' => ActionScheduler_Store::STATUS_PENDING, |
|
89 | - 'modified' => $cutoff, |
|
90 | - 'modified_compare' => '<=', |
|
91 | - 'claimed' => true, |
|
92 | - 'per_page' => $this->get_batch_size(), |
|
93 | - ) ); |
|
94 | - |
|
95 | - foreach ( $actions_to_reset as $action_id ) { |
|
96 | - $this->store->unclaim_action( $action_id ); |
|
97 | - do_action( 'action_scheduler_reset_action', $action_id ); |
|
98 | - } |
|
99 | - } |
|
100 | - |
|
101 | - /** |
|
102 | - * Mark actions that have been running for more than a given time limit as failed, based on |
|
103 | - * the assumption some uncatachable and unloggable fatal error occurred during processing. |
|
104 | - * |
|
105 | - * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
106 | - * as a parameter is 10x the time limit used for queue processing. |
|
107 | - * |
|
108 | - * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes). |
|
109 | - */ |
|
110 | - public function mark_failures( $time_limit = 300 ) { |
|
111 | - $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit ); |
|
112 | - if ( $timeout < 0 ) { |
|
113 | - return; |
|
114 | - } |
|
115 | - $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
116 | - $actions_to_reset = $this->store->query_actions( array( |
|
117 | - 'status' => ActionScheduler_Store::STATUS_RUNNING, |
|
118 | - 'modified' => $cutoff, |
|
119 | - 'modified_compare' => '<=', |
|
120 | - 'per_page' => $this->get_batch_size(), |
|
121 | - ) ); |
|
122 | - |
|
123 | - foreach ( $actions_to_reset as $action_id ) { |
|
124 | - $this->store->mark_failure( $action_id ); |
|
125 | - do_action( 'action_scheduler_failed_action', $action_id, $timeout ); |
|
126 | - } |
|
127 | - } |
|
128 | - |
|
129 | - /** |
|
130 | - * Do all of the cleaning actions. |
|
131 | - * |
|
132 | - * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes). |
|
133 | - * @author Jeremy Pry |
|
134 | - */ |
|
135 | - public function clean( $time_limit = 300 ) { |
|
136 | - $this->delete_old_actions(); |
|
137 | - $this->reset_timeouts( $time_limit ); |
|
138 | - $this->mark_failures( $time_limit ); |
|
139 | - } |
|
140 | - |
|
141 | - /** |
|
142 | - * Get the batch size for cleaning the queue. |
|
143 | - * |
|
144 | - * @author Jeremy Pry |
|
145 | - * @return int |
|
146 | - */ |
|
147 | - protected function get_batch_size() { |
|
148 | - /** |
|
149 | - * Filter the batch size when cleaning the queue. |
|
150 | - * |
|
151 | - * @param int $batch_size The number of actions to clean in one batch. |
|
152 | - */ |
|
153 | - return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) ); |
|
154 | - } |
|
8 | + /** @var int */ |
|
9 | + protected $batch_size; |
|
10 | + |
|
11 | + /** @var ActionScheduler_Store */ |
|
12 | + private $store = null; |
|
13 | + |
|
14 | + /** |
|
15 | + * 31 days in seconds. |
|
16 | + * |
|
17 | + * @var int |
|
18 | + */ |
|
19 | + private $month_in_seconds = 2678400; |
|
20 | + |
|
21 | + /** |
|
22 | + * ActionScheduler_QueueCleaner constructor. |
|
23 | + * |
|
24 | + * @param ActionScheduler_Store $store The store instance. |
|
25 | + * @param int $batch_size The batch size. |
|
26 | + */ |
|
27 | + public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) { |
|
28 | + $this->store = $store ? $store : ActionScheduler_Store::instance(); |
|
29 | + $this->batch_size = $batch_size; |
|
30 | + } |
|
31 | + |
|
32 | + public function delete_old_actions() { |
|
33 | + $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds ); |
|
34 | + $cutoff = as_get_datetime_object($lifespan.' seconds ago'); |
|
35 | + |
|
36 | + $statuses_to_purge = array( |
|
37 | + ActionScheduler_Store::STATUS_COMPLETE, |
|
38 | + ActionScheduler_Store::STATUS_CANCELED, |
|
39 | + ); |
|
40 | + |
|
41 | + foreach ( $statuses_to_purge as $status ) { |
|
42 | + $actions_to_delete = $this->store->query_actions( array( |
|
43 | + 'status' => $status, |
|
44 | + 'modified' => $cutoff, |
|
45 | + 'modified_compare' => '<=', |
|
46 | + 'per_page' => $this->get_batch_size(), |
|
47 | + ) ); |
|
48 | + |
|
49 | + foreach ( $actions_to_delete as $action_id ) { |
|
50 | + try { |
|
51 | + $this->store->delete_action( $action_id ); |
|
52 | + } catch ( Exception $e ) { |
|
53 | + |
|
54 | + /** |
|
55 | + * Notify 3rd party code of exceptions when deleting a completed action older than the retention period |
|
56 | + * |
|
57 | + * This hook provides a way for 3rd party code to log or otherwise handle exceptions relating to their |
|
58 | + * actions. |
|
59 | + * |
|
60 | + * @since 2.0.0 |
|
61 | + * |
|
62 | + * @param int $action_id The scheduled actions ID in the data store |
|
63 | + * @param Exception $e The exception thrown when attempting to delete the action from the data store |
|
64 | + * @param int $lifespan The retention period, in seconds, for old actions |
|
65 | + * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch |
|
66 | + */ |
|
67 | + do_action( 'action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count( $actions_to_delete ) ); |
|
68 | + } |
|
69 | + } |
|
70 | + } |
|
71 | + } |
|
72 | + |
|
73 | + /** |
|
74 | + * Unclaim pending actions that have not been run within a given time limit. |
|
75 | + * |
|
76 | + * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
77 | + * as a parameter is 10x the time limit used for queue processing. |
|
78 | + * |
|
79 | + * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes). |
|
80 | + */ |
|
81 | + public function reset_timeouts( $time_limit = 300 ) { |
|
82 | + $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit ); |
|
83 | + if ( $timeout < 0 ) { |
|
84 | + return; |
|
85 | + } |
|
86 | + $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
87 | + $actions_to_reset = $this->store->query_actions( array( |
|
88 | + 'status' => ActionScheduler_Store::STATUS_PENDING, |
|
89 | + 'modified' => $cutoff, |
|
90 | + 'modified_compare' => '<=', |
|
91 | + 'claimed' => true, |
|
92 | + 'per_page' => $this->get_batch_size(), |
|
93 | + ) ); |
|
94 | + |
|
95 | + foreach ( $actions_to_reset as $action_id ) { |
|
96 | + $this->store->unclaim_action( $action_id ); |
|
97 | + do_action( 'action_scheduler_reset_action', $action_id ); |
|
98 | + } |
|
99 | + } |
|
100 | + |
|
101 | + /** |
|
102 | + * Mark actions that have been running for more than a given time limit as failed, based on |
|
103 | + * the assumption some uncatachable and unloggable fatal error occurred during processing. |
|
104 | + * |
|
105 | + * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
106 | + * as a parameter is 10x the time limit used for queue processing. |
|
107 | + * |
|
108 | + * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes). |
|
109 | + */ |
|
110 | + public function mark_failures( $time_limit = 300 ) { |
|
111 | + $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit ); |
|
112 | + if ( $timeout < 0 ) { |
|
113 | + return; |
|
114 | + } |
|
115 | + $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
116 | + $actions_to_reset = $this->store->query_actions( array( |
|
117 | + 'status' => ActionScheduler_Store::STATUS_RUNNING, |
|
118 | + 'modified' => $cutoff, |
|
119 | + 'modified_compare' => '<=', |
|
120 | + 'per_page' => $this->get_batch_size(), |
|
121 | + ) ); |
|
122 | + |
|
123 | + foreach ( $actions_to_reset as $action_id ) { |
|
124 | + $this->store->mark_failure( $action_id ); |
|
125 | + do_action( 'action_scheduler_failed_action', $action_id, $timeout ); |
|
126 | + } |
|
127 | + } |
|
128 | + |
|
129 | + /** |
|
130 | + * Do all of the cleaning actions. |
|
131 | + * |
|
132 | + * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes). |
|
133 | + * @author Jeremy Pry |
|
134 | + */ |
|
135 | + public function clean( $time_limit = 300 ) { |
|
136 | + $this->delete_old_actions(); |
|
137 | + $this->reset_timeouts( $time_limit ); |
|
138 | + $this->mark_failures( $time_limit ); |
|
139 | + } |
|
140 | + |
|
141 | + /** |
|
142 | + * Get the batch size for cleaning the queue. |
|
143 | + * |
|
144 | + * @author Jeremy Pry |
|
145 | + * @return int |
|
146 | + */ |
|
147 | + protected function get_batch_size() { |
|
148 | + /** |
|
149 | + * Filter the batch size when cleaning the queue. |
|
150 | + * |
|
151 | + * @param int $batch_size The number of actions to clean in one batch. |
|
152 | + */ |
|
153 | + return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) ); |
|
154 | + } |
|
155 | 155 | } |
@@ -24,32 +24,32 @@ discard block |
||
24 | 24 | * @param ActionScheduler_Store $store The store instance. |
25 | 25 | * @param int $batch_size The batch size. |
26 | 26 | */ |
27 | - public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) { |
|
27 | + public function __construct(ActionScheduler_Store $store = null, $batch_size = 20) { |
|
28 | 28 | $this->store = $store ? $store : ActionScheduler_Store::instance(); |
29 | 29 | $this->batch_size = $batch_size; |
30 | 30 | } |
31 | 31 | |
32 | 32 | public function delete_old_actions() { |
33 | - $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds ); |
|
34 | - $cutoff = as_get_datetime_object($lifespan.' seconds ago'); |
|
33 | + $lifespan = apply_filters('action_scheduler_retention_period', $this->month_in_seconds); |
|
34 | + $cutoff = as_get_datetime_object($lifespan . ' seconds ago'); |
|
35 | 35 | |
36 | 36 | $statuses_to_purge = array( |
37 | 37 | ActionScheduler_Store::STATUS_COMPLETE, |
38 | 38 | ActionScheduler_Store::STATUS_CANCELED, |
39 | 39 | ); |
40 | 40 | |
41 | - foreach ( $statuses_to_purge as $status ) { |
|
42 | - $actions_to_delete = $this->store->query_actions( array( |
|
41 | + foreach ($statuses_to_purge as $status) { |
|
42 | + $actions_to_delete = $this->store->query_actions(array( |
|
43 | 43 | 'status' => $status, |
44 | 44 | 'modified' => $cutoff, |
45 | 45 | 'modified_compare' => '<=', |
46 | 46 | 'per_page' => $this->get_batch_size(), |
47 | - ) ); |
|
47 | + )); |
|
48 | 48 | |
49 | - foreach ( $actions_to_delete as $action_id ) { |
|
49 | + foreach ($actions_to_delete as $action_id) { |
|
50 | 50 | try { |
51 | - $this->store->delete_action( $action_id ); |
|
52 | - } catch ( Exception $e ) { |
|
51 | + $this->store->delete_action($action_id); |
|
52 | + } catch (Exception $e) { |
|
53 | 53 | |
54 | 54 | /** |
55 | 55 | * Notify 3rd party code of exceptions when deleting a completed action older than the retention period |
@@ -64,7 +64,7 @@ discard block |
||
64 | 64 | * @param int $lifespan The retention period, in seconds, for old actions |
65 | 65 | * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch |
66 | 66 | */ |
67 | - do_action( 'action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count( $actions_to_delete ) ); |
|
67 | + do_action('action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count($actions_to_delete)); |
|
68 | 68 | } |
69 | 69 | } |
70 | 70 | } |
@@ -78,23 +78,23 @@ discard block |
||
78 | 78 | * |
79 | 79 | * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes). |
80 | 80 | */ |
81 | - public function reset_timeouts( $time_limit = 300 ) { |
|
82 | - $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit ); |
|
83 | - if ( $timeout < 0 ) { |
|
81 | + public function reset_timeouts($time_limit = 300) { |
|
82 | + $timeout = apply_filters('action_scheduler_timeout_period', $time_limit); |
|
83 | + if ($timeout < 0) { |
|
84 | 84 | return; |
85 | 85 | } |
86 | - $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
87 | - $actions_to_reset = $this->store->query_actions( array( |
|
86 | + $cutoff = as_get_datetime_object($timeout . ' seconds ago'); |
|
87 | + $actions_to_reset = $this->store->query_actions(array( |
|
88 | 88 | 'status' => ActionScheduler_Store::STATUS_PENDING, |
89 | 89 | 'modified' => $cutoff, |
90 | 90 | 'modified_compare' => '<=', |
91 | 91 | 'claimed' => true, |
92 | 92 | 'per_page' => $this->get_batch_size(), |
93 | - ) ); |
|
93 | + )); |
|
94 | 94 | |
95 | - foreach ( $actions_to_reset as $action_id ) { |
|
96 | - $this->store->unclaim_action( $action_id ); |
|
97 | - do_action( 'action_scheduler_reset_action', $action_id ); |
|
95 | + foreach ($actions_to_reset as $action_id) { |
|
96 | + $this->store->unclaim_action($action_id); |
|
97 | + do_action('action_scheduler_reset_action', $action_id); |
|
98 | 98 | } |
99 | 99 | } |
100 | 100 | |
@@ -107,22 +107,22 @@ discard block |
||
107 | 107 | * |
108 | 108 | * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes). |
109 | 109 | */ |
110 | - public function mark_failures( $time_limit = 300 ) { |
|
111 | - $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit ); |
|
112 | - if ( $timeout < 0 ) { |
|
110 | + public function mark_failures($time_limit = 300) { |
|
111 | + $timeout = apply_filters('action_scheduler_failure_period', $time_limit); |
|
112 | + if ($timeout < 0) { |
|
113 | 113 | return; |
114 | 114 | } |
115 | - $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
116 | - $actions_to_reset = $this->store->query_actions( array( |
|
115 | + $cutoff = as_get_datetime_object($timeout . ' seconds ago'); |
|
116 | + $actions_to_reset = $this->store->query_actions(array( |
|
117 | 117 | 'status' => ActionScheduler_Store::STATUS_RUNNING, |
118 | 118 | 'modified' => $cutoff, |
119 | 119 | 'modified_compare' => '<=', |
120 | 120 | 'per_page' => $this->get_batch_size(), |
121 | - ) ); |
|
121 | + )); |
|
122 | 122 | |
123 | - foreach ( $actions_to_reset as $action_id ) { |
|
124 | - $this->store->mark_failure( $action_id ); |
|
125 | - do_action( 'action_scheduler_failed_action', $action_id, $timeout ); |
|
123 | + foreach ($actions_to_reset as $action_id) { |
|
124 | + $this->store->mark_failure($action_id); |
|
125 | + do_action('action_scheduler_failed_action', $action_id, $timeout); |
|
126 | 126 | } |
127 | 127 | } |
128 | 128 | |
@@ -132,10 +132,10 @@ discard block |
||
132 | 132 | * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes). |
133 | 133 | * @author Jeremy Pry |
134 | 134 | */ |
135 | - public function clean( $time_limit = 300 ) { |
|
135 | + public function clean($time_limit = 300) { |
|
136 | 136 | $this->delete_old_actions(); |
137 | - $this->reset_timeouts( $time_limit ); |
|
138 | - $this->mark_failures( $time_limit ); |
|
137 | + $this->reset_timeouts($time_limit); |
|
138 | + $this->mark_failures($time_limit); |
|
139 | 139 | } |
140 | 140 | |
141 | 141 | /** |
@@ -150,6 +150,6 @@ discard block |
||
150 | 150 | * |
151 | 151 | * @param int $batch_size The number of actions to clean in one batch. |
152 | 152 | */ |
153 | - return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) ); |
|
153 | + return absint(apply_filters('action_scheduler_cleanup_batch_size', $this->batch_size)); |
|
154 | 154 | } |
155 | 155 | } |
@@ -9,41 +9,41 @@ |
||
9 | 9 | */ |
10 | 10 | class ActionScheduler_OptionLock extends ActionScheduler_Lock { |
11 | 11 | |
12 | - /** |
|
13 | - * Set a lock using options for a given amount of time (60 seconds by default). |
|
14 | - * |
|
15 | - * Using an autoloaded option avoids running database queries or other resource intensive tasks |
|
16 | - * on frequently triggered hooks, like 'init' or 'shutdown'. |
|
17 | - * |
|
18 | - * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid |
|
19 | - * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', |
|
20 | - * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() |
|
21 | - * to find the current number of claims in the database. |
|
22 | - * |
|
23 | - * @param string $lock_type A string to identify different lock types. |
|
24 | - * @bool True if lock value has changed, false if not or if set failed. |
|
25 | - */ |
|
26 | - public function set( $lock_type ) { |
|
27 | - return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
28 | - } |
|
12 | + /** |
|
13 | + * Set a lock using options for a given amount of time (60 seconds by default). |
|
14 | + * |
|
15 | + * Using an autoloaded option avoids running database queries or other resource intensive tasks |
|
16 | + * on frequently triggered hooks, like 'init' or 'shutdown'. |
|
17 | + * |
|
18 | + * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid |
|
19 | + * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', |
|
20 | + * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() |
|
21 | + * to find the current number of claims in the database. |
|
22 | + * |
|
23 | + * @param string $lock_type A string to identify different lock types. |
|
24 | + * @bool True if lock value has changed, false if not or if set failed. |
|
25 | + */ |
|
26 | + public function set( $lock_type ) { |
|
27 | + return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
28 | + } |
|
29 | 29 | |
30 | - /** |
|
31 | - * If a lock is set, return the timestamp it was set to expiry. |
|
32 | - * |
|
33 | - * @param string $lock_type A string to identify different lock types. |
|
34 | - * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
|
35 | - */ |
|
36 | - public function get_expiration( $lock_type ) { |
|
37 | - return get_option( $this->get_key( $lock_type ) ); |
|
38 | - } |
|
30 | + /** |
|
31 | + * If a lock is set, return the timestamp it was set to expiry. |
|
32 | + * |
|
33 | + * @param string $lock_type A string to identify different lock types. |
|
34 | + * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
|
35 | + */ |
|
36 | + public function get_expiration( $lock_type ) { |
|
37 | + return get_option( $this->get_key( $lock_type ) ); |
|
38 | + } |
|
39 | 39 | |
40 | - /** |
|
41 | - * Get the key to use for storing the lock in the transient |
|
42 | - * |
|
43 | - * @param string $lock_type A string to identify different lock types. |
|
44 | - * @return string |
|
45 | - */ |
|
46 | - protected function get_key( $lock_type ) { |
|
47 | - return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
48 | - } |
|
40 | + /** |
|
41 | + * Get the key to use for storing the lock in the transient |
|
42 | + * |
|
43 | + * @param string $lock_type A string to identify different lock types. |
|
44 | + * @return string |
|
45 | + */ |
|
46 | + protected function get_key( $lock_type ) { |
|
47 | + return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
48 | + } |
|
49 | 49 | } |
@@ -23,8 +23,8 @@ discard block |
||
23 | 23 | * @param string $lock_type A string to identify different lock types. |
24 | 24 | * @bool True if lock value has changed, false if not or if set failed. |
25 | 25 | */ |
26 | - public function set( $lock_type ) { |
|
27 | - return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
26 | + public function set($lock_type) { |
|
27 | + return update_option($this->get_key($lock_type), time() + $this->get_duration($lock_type)); |
|
28 | 28 | } |
29 | 29 | |
30 | 30 | /** |
@@ -33,8 +33,8 @@ discard block |
||
33 | 33 | * @param string $lock_type A string to identify different lock types. |
34 | 34 | * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
35 | 35 | */ |
36 | - public function get_expiration( $lock_type ) { |
|
37 | - return get_option( $this->get_key( $lock_type ) ); |
|
36 | + public function get_expiration($lock_type) { |
|
37 | + return get_option($this->get_key($lock_type)); |
|
38 | 38 | } |
39 | 39 | |
40 | 40 | /** |
@@ -43,7 +43,7 @@ discard block |
||
43 | 43 | * @param string $lock_type A string to identify different lock types. |
44 | 44 | * @return string |
45 | 45 | */ |
46 | - protected function get_key( $lock_type ) { |
|
47 | - return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
46 | + protected function get_key($lock_type) { |
|
47 | + return sprintf('action_scheduler_lock_%s', $lock_type); |
|
48 | 48 | } |
49 | 49 | } |
@@ -4,20 +4,20 @@ |
||
4 | 4 | * Class ActionScheduler_ActionClaim |
5 | 5 | */ |
6 | 6 | class ActionScheduler_ActionClaim { |
7 | - private $id = ''; |
|
8 | - private $action_ids = array(); |
|
7 | + private $id = ''; |
|
8 | + private $action_ids = array(); |
|
9 | 9 | |
10 | - public function __construct( $id, array $action_ids ) { |
|
11 | - $this->id = $id; |
|
12 | - $this->action_ids = $action_ids; |
|
13 | - } |
|
10 | + public function __construct( $id, array $action_ids ) { |
|
11 | + $this->id = $id; |
|
12 | + $this->action_ids = $action_ids; |
|
13 | + } |
|
14 | 14 | |
15 | - public function get_id() { |
|
16 | - return $this->id; |
|
17 | - } |
|
15 | + public function get_id() { |
|
16 | + return $this->id; |
|
17 | + } |
|
18 | 18 | |
19 | - public function get_actions() { |
|
20 | - return $this->action_ids; |
|
21 | - } |
|
19 | + public function get_actions() { |
|
20 | + return $this->action_ids; |
|
21 | + } |
|
22 | 22 | } |
23 | - |
|
24 | 23 | \ No newline at end of file |
24 | + |
|
25 | 25 | \ No newline at end of file |
@@ -7,7 +7,7 @@ |
||
7 | 7 | private $id = ''; |
8 | 8 | private $action_ids = array(); |
9 | 9 | |
10 | - public function __construct( $id, array $action_ids ) { |
|
10 | + public function __construct($id, array $action_ids) { |
|
11 | 11 | $this->id = $id; |
12 | 12 | $this->action_ids = $action_ids; |
13 | 13 | } |
@@ -4,195 +4,195 @@ |
||
4 | 4 | * Class ActionScheduler_QueueRunner |
5 | 5 | */ |
6 | 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 | - /** |
|
18 | - * @return ActionScheduler_QueueRunner |
|
19 | - * @codeCoverageIgnore |
|
20 | - */ |
|
21 | - public static function instance() { |
|
22 | - if ( empty(self::$runner) ) { |
|
23 | - $class = apply_filters('action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner'); |
|
24 | - self::$runner = new $class(); |
|
25 | - } |
|
26 | - return self::$runner; |
|
27 | - } |
|
28 | - |
|
29 | - /** |
|
30 | - * ActionScheduler_QueueRunner constructor. |
|
31 | - * |
|
32 | - * @param ActionScheduler_Store $store |
|
33 | - * @param ActionScheduler_FatalErrorMonitor $monitor |
|
34 | - * @param ActionScheduler_QueueCleaner $cleaner |
|
35 | - */ |
|
36 | - public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) { |
|
37 | - parent::__construct( $store, $monitor, $cleaner ); |
|
38 | - |
|
39 | - if ( is_null( $async_request ) ) { |
|
40 | - $async_request = new ActionScheduler_AsyncRequest_QueueRunner( $this->store ); |
|
41 | - } |
|
42 | - |
|
43 | - $this->async_request = $async_request; |
|
44 | - } |
|
45 | - |
|
46 | - /** |
|
47 | - * @codeCoverageIgnore |
|
48 | - */ |
|
49 | - public function init() { |
|
50 | - |
|
51 | - add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) ); |
|
52 | - |
|
53 | - $cron_context = array( 'WP Cron' ); |
|
54 | - |
|
55 | - if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) { |
|
56 | - |
|
57 | - // Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param |
|
58 | - $next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK ); |
|
59 | - if ( $next_timestamp ) { |
|
60 | - wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK ); |
|
61 | - } |
|
62 | - |
|
63 | - $schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE ); |
|
64 | - wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context ); |
|
65 | - } |
|
66 | - |
|
67 | - add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) ); |
|
68 | - $this->hook_dispatch_async_request(); |
|
69 | - } |
|
70 | - |
|
71 | - /** |
|
72 | - * Hook check for dispatching an async request. |
|
73 | - */ |
|
74 | - public function hook_dispatch_async_request() { |
|
75 | - add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); |
|
76 | - } |
|
77 | - |
|
78 | - /** |
|
79 | - * Unhook check for dispatching an async request. |
|
80 | - */ |
|
81 | - public function unhook_dispatch_async_request() { |
|
82 | - remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); |
|
83 | - } |
|
84 | - |
|
85 | - /** |
|
86 | - * Check if we should dispatch an async request to process actions. |
|
87 | - * |
|
88 | - * This method is attached to 'shutdown', so is called frequently. To avoid slowing down |
|
89 | - * the site, it mitigates the work performed in each request by: |
|
90 | - * 1. checking if it's in the admin context and then |
|
91 | - * 2. haven't run on the 'shutdown' hook within the lock time (60 seconds by default) |
|
92 | - * 3. haven't exceeded the number of allowed batches. |
|
93 | - * |
|
94 | - * The order of these checks is important, because they run from a check on a value: |
|
95 | - * 1. in memory - is_admin() maps to $GLOBALS or the WP_ADMIN constant |
|
96 | - * 2. in memory - transients use autoloaded options by default |
|
97 | - * 3. from a database query - has_maximum_concurrent_batches() run the query |
|
98 | - * $this->store->get_claim_count() to find the current number of claims in the DB. |
|
99 | - * |
|
100 | - * If all of these conditions are met, then we request an async runner check whether it |
|
101 | - * should dispatch a request to process pending actions. |
|
102 | - */ |
|
103 | - public function maybe_dispatch_async_request() { |
|
104 | - if ( is_admin() && ! ActionScheduler::lock()->is_locked( 'async-request-runner' ) ) { |
|
105 | - // Only start an async queue at most once every 60 seconds |
|
106 | - ActionScheduler::lock()->set( 'async-request-runner' ); |
|
107 | - $this->async_request->maybe_dispatch(); |
|
108 | - } |
|
109 | - } |
|
110 | - |
|
111 | - /** |
|
112 | - * Process actions in the queue. Attached to self::WP_CRON_HOOK i.e. 'action_scheduler_run_queue' |
|
113 | - * |
|
114 | - * The $context param of this method defaults to 'WP Cron', because prior to Action Scheduler 3.0.0 |
|
115 | - * that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context |
|
116 | - * passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK, |
|
117 | - * should set a context as the first parameter. For an example of this, refer to the code seen in |
|
118 | - * @see ActionScheduler_AsyncRequest_QueueRunner::handle() |
|
119 | - * |
|
120 | - * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' |
|
121 | - * Generally, this should be capitalised and not localised as it's a proper noun. |
|
122 | - * @return int The number of actions processed. |
|
123 | - */ |
|
124 | - public function run( $context = 'WP Cron' ) { |
|
125 | - ActionScheduler_Compatibility::raise_memory_limit(); |
|
126 | - ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() ); |
|
127 | - do_action( 'action_scheduler_before_process_queue' ); |
|
128 | - $this->run_cleanup(); |
|
129 | - $processed_actions = 0; |
|
130 | - if ( false === $this->has_maximum_concurrent_batches() ) { |
|
131 | - $batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 ); |
|
132 | - do { |
|
133 | - $processed_actions_in_batch = $this->do_batch( $batch_size, $context ); |
|
134 | - $processed_actions += $processed_actions_in_batch; |
|
135 | - } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $processed_actions ) ); // keep going until we run out of actions, time, or memory |
|
136 | - } |
|
137 | - |
|
138 | - do_action( 'action_scheduler_after_process_queue' ); |
|
139 | - return $processed_actions; |
|
140 | - } |
|
141 | - |
|
142 | - /** |
|
143 | - * Process a batch of actions pending in the queue. |
|
144 | - * |
|
145 | - * Actions are processed by claiming a set of pending actions then processing each one until either the batch |
|
146 | - * size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded(). |
|
147 | - * |
|
148 | - * @param int $size The maximum number of actions to process in the batch. |
|
149 | - * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' |
|
150 | - * Generally, this should be capitalised and not localised as it's a proper noun. |
|
151 | - * @return int The number of actions processed. |
|
152 | - */ |
|
153 | - protected function do_batch( $size = 100, $context = '' ) { |
|
154 | - $claim = $this->store->stake_claim($size); |
|
155 | - $this->monitor->attach($claim); |
|
156 | - $processed_actions = 0; |
|
157 | - |
|
158 | - foreach ( $claim->get_actions() as $action_id ) { |
|
159 | - // bail if we lost the claim |
|
160 | - if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) { |
|
161 | - break; |
|
162 | - } |
|
163 | - $this->process_action( $action_id, $context ); |
|
164 | - $processed_actions++; |
|
165 | - |
|
166 | - if ( $this->batch_limits_exceeded( $processed_actions ) ) { |
|
167 | - break; |
|
168 | - } |
|
169 | - } |
|
170 | - $this->store->release_claim($claim); |
|
171 | - $this->monitor->detach(); |
|
172 | - $this->clear_caches(); |
|
173 | - return $processed_actions; |
|
174 | - } |
|
175 | - |
|
176 | - /** |
|
177 | - * Running large batches can eat up memory, as WP adds data to its object cache. |
|
178 | - * |
|
179 | - * If using a persistent object store, this has the side effect of flushing that |
|
180 | - * as well, so this is disabled by default. To enable: |
|
181 | - * |
|
182 | - * add_filter( 'action_scheduler_queue_runner_flush_cache', '__return_true' ); |
|
183 | - */ |
|
184 | - protected function clear_caches() { |
|
185 | - if ( ! wp_using_ext_object_cache() || apply_filters( 'action_scheduler_queue_runner_flush_cache', false ) ) { |
|
186 | - wp_cache_flush(); |
|
187 | - } |
|
188 | - } |
|
189 | - |
|
190 | - public function add_wp_cron_schedule( $schedules ) { |
|
191 | - $schedules['every_minute'] = array( |
|
192 | - 'interval' => 60, // in seconds |
|
193 | - 'display' => __( 'Every minute', 'action-scheduler' ), |
|
194 | - ); |
|
195 | - |
|
196 | - return $schedules; |
|
197 | - } |
|
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 | + /** |
|
18 | + * @return ActionScheduler_QueueRunner |
|
19 | + * @codeCoverageIgnore |
|
20 | + */ |
|
21 | + public static function instance() { |
|
22 | + if ( empty(self::$runner) ) { |
|
23 | + $class = apply_filters('action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner'); |
|
24 | + self::$runner = new $class(); |
|
25 | + } |
|
26 | + return self::$runner; |
|
27 | + } |
|
28 | + |
|
29 | + /** |
|
30 | + * ActionScheduler_QueueRunner constructor. |
|
31 | + * |
|
32 | + * @param ActionScheduler_Store $store |
|
33 | + * @param ActionScheduler_FatalErrorMonitor $monitor |
|
34 | + * @param ActionScheduler_QueueCleaner $cleaner |
|
35 | + */ |
|
36 | + public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) { |
|
37 | + parent::__construct( $store, $monitor, $cleaner ); |
|
38 | + |
|
39 | + if ( is_null( $async_request ) ) { |
|
40 | + $async_request = new ActionScheduler_AsyncRequest_QueueRunner( $this->store ); |
|
41 | + } |
|
42 | + |
|
43 | + $this->async_request = $async_request; |
|
44 | + } |
|
45 | + |
|
46 | + /** |
|
47 | + * @codeCoverageIgnore |
|
48 | + */ |
|
49 | + public function init() { |
|
50 | + |
|
51 | + add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) ); |
|
52 | + |
|
53 | + $cron_context = array( 'WP Cron' ); |
|
54 | + |
|
55 | + if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) { |
|
56 | + |
|
57 | + // Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param |
|
58 | + $next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK ); |
|
59 | + if ( $next_timestamp ) { |
|
60 | + wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK ); |
|
61 | + } |
|
62 | + |
|
63 | + $schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE ); |
|
64 | + wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context ); |
|
65 | + } |
|
66 | + |
|
67 | + add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) ); |
|
68 | + $this->hook_dispatch_async_request(); |
|
69 | + } |
|
70 | + |
|
71 | + /** |
|
72 | + * Hook check for dispatching an async request. |
|
73 | + */ |
|
74 | + public function hook_dispatch_async_request() { |
|
75 | + add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); |
|
76 | + } |
|
77 | + |
|
78 | + /** |
|
79 | + * Unhook check for dispatching an async request. |
|
80 | + */ |
|
81 | + public function unhook_dispatch_async_request() { |
|
82 | + remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); |
|
83 | + } |
|
84 | + |
|
85 | + /** |
|
86 | + * Check if we should dispatch an async request to process actions. |
|
87 | + * |
|
88 | + * This method is attached to 'shutdown', so is called frequently. To avoid slowing down |
|
89 | + * the site, it mitigates the work performed in each request by: |
|
90 | + * 1. checking if it's in the admin context and then |
|
91 | + * 2. haven't run on the 'shutdown' hook within the lock time (60 seconds by default) |
|
92 | + * 3. haven't exceeded the number of allowed batches. |
|
93 | + * |
|
94 | + * The order of these checks is important, because they run from a check on a value: |
|
95 | + * 1. in memory - is_admin() maps to $GLOBALS or the WP_ADMIN constant |
|
96 | + * 2. in memory - transients use autoloaded options by default |
|
97 | + * 3. from a database query - has_maximum_concurrent_batches() run the query |
|
98 | + * $this->store->get_claim_count() to find the current number of claims in the DB. |
|
99 | + * |
|
100 | + * If all of these conditions are met, then we request an async runner check whether it |
|
101 | + * should dispatch a request to process pending actions. |
|
102 | + */ |
|
103 | + public function maybe_dispatch_async_request() { |
|
104 | + if ( is_admin() && ! ActionScheduler::lock()->is_locked( 'async-request-runner' ) ) { |
|
105 | + // Only start an async queue at most once every 60 seconds |
|
106 | + ActionScheduler::lock()->set( 'async-request-runner' ); |
|
107 | + $this->async_request->maybe_dispatch(); |
|
108 | + } |
|
109 | + } |
|
110 | + |
|
111 | + /** |
|
112 | + * Process actions in the queue. Attached to self::WP_CRON_HOOK i.e. 'action_scheduler_run_queue' |
|
113 | + * |
|
114 | + * The $context param of this method defaults to 'WP Cron', because prior to Action Scheduler 3.0.0 |
|
115 | + * that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context |
|
116 | + * passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK, |
|
117 | + * should set a context as the first parameter. For an example of this, refer to the code seen in |
|
118 | + * @see ActionScheduler_AsyncRequest_QueueRunner::handle() |
|
119 | + * |
|
120 | + * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' |
|
121 | + * Generally, this should be capitalised and not localised as it's a proper noun. |
|
122 | + * @return int The number of actions processed. |
|
123 | + */ |
|
124 | + public function run( $context = 'WP Cron' ) { |
|
125 | + ActionScheduler_Compatibility::raise_memory_limit(); |
|
126 | + ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() ); |
|
127 | + do_action( 'action_scheduler_before_process_queue' ); |
|
128 | + $this->run_cleanup(); |
|
129 | + $processed_actions = 0; |
|
130 | + if ( false === $this->has_maximum_concurrent_batches() ) { |
|
131 | + $batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 ); |
|
132 | + do { |
|
133 | + $processed_actions_in_batch = $this->do_batch( $batch_size, $context ); |
|
134 | + $processed_actions += $processed_actions_in_batch; |
|
135 | + } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $processed_actions ) ); // keep going until we run out of actions, time, or memory |
|
136 | + } |
|
137 | + |
|
138 | + do_action( 'action_scheduler_after_process_queue' ); |
|
139 | + return $processed_actions; |
|
140 | + } |
|
141 | + |
|
142 | + /** |
|
143 | + * Process a batch of actions pending in the queue. |
|
144 | + * |
|
145 | + * Actions are processed by claiming a set of pending actions then processing each one until either the batch |
|
146 | + * size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded(). |
|
147 | + * |
|
148 | + * @param int $size The maximum number of actions to process in the batch. |
|
149 | + * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' |
|
150 | + * Generally, this should be capitalised and not localised as it's a proper noun. |
|
151 | + * @return int The number of actions processed. |
|
152 | + */ |
|
153 | + protected function do_batch( $size = 100, $context = '' ) { |
|
154 | + $claim = $this->store->stake_claim($size); |
|
155 | + $this->monitor->attach($claim); |
|
156 | + $processed_actions = 0; |
|
157 | + |
|
158 | + foreach ( $claim->get_actions() as $action_id ) { |
|
159 | + // bail if we lost the claim |
|
160 | + if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) { |
|
161 | + break; |
|
162 | + } |
|
163 | + $this->process_action( $action_id, $context ); |
|
164 | + $processed_actions++; |
|
165 | + |
|
166 | + if ( $this->batch_limits_exceeded( $processed_actions ) ) { |
|
167 | + break; |
|
168 | + } |
|
169 | + } |
|
170 | + $this->store->release_claim($claim); |
|
171 | + $this->monitor->detach(); |
|
172 | + $this->clear_caches(); |
|
173 | + return $processed_actions; |
|
174 | + } |
|
175 | + |
|
176 | + /** |
|
177 | + * Running large batches can eat up memory, as WP adds data to its object cache. |
|
178 | + * |
|
179 | + * If using a persistent object store, this has the side effect of flushing that |
|
180 | + * as well, so this is disabled by default. To enable: |
|
181 | + * |
|
182 | + * add_filter( 'action_scheduler_queue_runner_flush_cache', '__return_true' ); |
|
183 | + */ |
|
184 | + protected function clear_caches() { |
|
185 | + if ( ! wp_using_ext_object_cache() || apply_filters( 'action_scheduler_queue_runner_flush_cache', false ) ) { |
|
186 | + wp_cache_flush(); |
|
187 | + } |
|
188 | + } |
|
189 | + |
|
190 | + public function add_wp_cron_schedule( $schedules ) { |
|
191 | + $schedules['every_minute'] = array( |
|
192 | + 'interval' => 60, // in seconds |
|
193 | + 'display' => __( 'Every minute', 'action-scheduler' ), |
|
194 | + ); |
|
195 | + |
|
196 | + return $schedules; |
|
197 | + } |
|
198 | 198 | } |
@@ -19,7 +19,7 @@ discard block |
||
19 | 19 | * @codeCoverageIgnore |
20 | 20 | */ |
21 | 21 | public static function instance() { |
22 | - if ( empty(self::$runner) ) { |
|
22 | + if (empty(self::$runner)) { |
|
23 | 23 | $class = apply_filters('action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner'); |
24 | 24 | self::$runner = new $class(); |
25 | 25 | } |
@@ -33,11 +33,11 @@ discard block |
||
33 | 33 | * @param ActionScheduler_FatalErrorMonitor $monitor |
34 | 34 | * @param ActionScheduler_QueueCleaner $cleaner |
35 | 35 | */ |
36 | - public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) { |
|
37 | - parent::__construct( $store, $monitor, $cleaner ); |
|
36 | + public function __construct(ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null) { |
|
37 | + parent::__construct($store, $monitor, $cleaner); |
|
38 | 38 | |
39 | - if ( is_null( $async_request ) ) { |
|
40 | - $async_request = new ActionScheduler_AsyncRequest_QueueRunner( $this->store ); |
|
39 | + if (is_null($async_request)) { |
|
40 | + $async_request = new ActionScheduler_AsyncRequest_QueueRunner($this->store); |
|
41 | 41 | } |
42 | 42 | |
43 | 43 | $this->async_request = $async_request; |
@@ -48,23 +48,23 @@ discard block |
||
48 | 48 | */ |
49 | 49 | public function init() { |
50 | 50 | |
51 | - add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) ); |
|
51 | + add_filter('cron_schedules', array(self::instance(), 'add_wp_cron_schedule')); |
|
52 | 52 | |
53 | - $cron_context = array( 'WP Cron' ); |
|
53 | + $cron_context = array('WP Cron'); |
|
54 | 54 | |
55 | - if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) { |
|
55 | + if (!wp_next_scheduled(self::WP_CRON_HOOK, $cron_context)) { |
|
56 | 56 | |
57 | 57 | // Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param |
58 | - $next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK ); |
|
59 | - if ( $next_timestamp ) { |
|
60 | - wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK ); |
|
58 | + $next_timestamp = wp_next_scheduled(self::WP_CRON_HOOK); |
|
59 | + if ($next_timestamp) { |
|
60 | + wp_unschedule_event($next_timestamp, self::WP_CRON_HOOK); |
|
61 | 61 | } |
62 | 62 | |
63 | - $schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE ); |
|
64 | - wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context ); |
|
63 | + $schedule = apply_filters('action_scheduler_run_schedule', self::WP_CRON_SCHEDULE); |
|
64 | + wp_schedule_event(time(), $schedule, self::WP_CRON_HOOK, $cron_context); |
|
65 | 65 | } |
66 | 66 | |
67 | - add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) ); |
|
67 | + add_action(self::WP_CRON_HOOK, array(self::instance(), 'run')); |
|
68 | 68 | $this->hook_dispatch_async_request(); |
69 | 69 | } |
70 | 70 | |
@@ -72,14 +72,14 @@ discard block |
||
72 | 72 | * Hook check for dispatching an async request. |
73 | 73 | */ |
74 | 74 | public function hook_dispatch_async_request() { |
75 | - add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); |
|
75 | + add_action('shutdown', array($this, 'maybe_dispatch_async_request')); |
|
76 | 76 | } |
77 | 77 | |
78 | 78 | /** |
79 | 79 | * Unhook check for dispatching an async request. |
80 | 80 | */ |
81 | 81 | public function unhook_dispatch_async_request() { |
82 | - remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); |
|
82 | + remove_action('shutdown', array($this, 'maybe_dispatch_async_request')); |
|
83 | 83 | } |
84 | 84 | |
85 | 85 | /** |
@@ -101,9 +101,9 @@ discard block |
||
101 | 101 | * should dispatch a request to process pending actions. |
102 | 102 | */ |
103 | 103 | public function maybe_dispatch_async_request() { |
104 | - if ( is_admin() && ! ActionScheduler::lock()->is_locked( 'async-request-runner' ) ) { |
|
104 | + if (is_admin() && !ActionScheduler::lock()->is_locked('async-request-runner')) { |
|
105 | 105 | // Only start an async queue at most once every 60 seconds |
106 | - ActionScheduler::lock()->set( 'async-request-runner' ); |
|
106 | + ActionScheduler::lock()->set('async-request-runner'); |
|
107 | 107 | $this->async_request->maybe_dispatch(); |
108 | 108 | } |
109 | 109 | } |
@@ -121,21 +121,21 @@ discard block |
||
121 | 121 | * Generally, this should be capitalised and not localised as it's a proper noun. |
122 | 122 | * @return int The number of actions processed. |
123 | 123 | */ |
124 | - public function run( $context = 'WP Cron' ) { |
|
124 | + public function run($context = 'WP Cron') { |
|
125 | 125 | ActionScheduler_Compatibility::raise_memory_limit(); |
126 | - ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() ); |
|
127 | - do_action( 'action_scheduler_before_process_queue' ); |
|
126 | + ActionScheduler_Compatibility::raise_time_limit($this->get_time_limit()); |
|
127 | + do_action('action_scheduler_before_process_queue'); |
|
128 | 128 | $this->run_cleanup(); |
129 | 129 | $processed_actions = 0; |
130 | - if ( false === $this->has_maximum_concurrent_batches() ) { |
|
131 | - $batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 ); |
|
130 | + if (false === $this->has_maximum_concurrent_batches()) { |
|
131 | + $batch_size = apply_filters('action_scheduler_queue_runner_batch_size', 25); |
|
132 | 132 | do { |
133 | - $processed_actions_in_batch = $this->do_batch( $batch_size, $context ); |
|
133 | + $processed_actions_in_batch = $this->do_batch($batch_size, $context); |
|
134 | 134 | $processed_actions += $processed_actions_in_batch; |
135 | - } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $processed_actions ) ); // keep going until we run out of actions, time, or memory |
|
135 | + } while ($processed_actions_in_batch > 0 && !$this->batch_limits_exceeded($processed_actions)); // keep going until we run out of actions, time, or memory |
|
136 | 136 | } |
137 | 137 | |
138 | - do_action( 'action_scheduler_after_process_queue' ); |
|
138 | + do_action('action_scheduler_after_process_queue'); |
|
139 | 139 | return $processed_actions; |
140 | 140 | } |
141 | 141 | |
@@ -150,20 +150,20 @@ discard block |
||
150 | 150 | * Generally, this should be capitalised and not localised as it's a proper noun. |
151 | 151 | * @return int The number of actions processed. |
152 | 152 | */ |
153 | - protected function do_batch( $size = 100, $context = '' ) { |
|
153 | + protected function do_batch($size = 100, $context = '') { |
|
154 | 154 | $claim = $this->store->stake_claim($size); |
155 | 155 | $this->monitor->attach($claim); |
156 | 156 | $processed_actions = 0; |
157 | 157 | |
158 | - foreach ( $claim->get_actions() as $action_id ) { |
|
158 | + foreach ($claim->get_actions() as $action_id) { |
|
159 | 159 | // bail if we lost the claim |
160 | - if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) { |
|
160 | + if (!in_array($action_id, $this->store->find_actions_by_claim_id($claim->get_id()))) { |
|
161 | 161 | break; |
162 | 162 | } |
163 | - $this->process_action( $action_id, $context ); |
|
163 | + $this->process_action($action_id, $context); |
|
164 | 164 | $processed_actions++; |
165 | 165 | |
166 | - if ( $this->batch_limits_exceeded( $processed_actions ) ) { |
|
166 | + if ($this->batch_limits_exceeded($processed_actions)) { |
|
167 | 167 | break; |
168 | 168 | } |
169 | 169 | } |
@@ -182,15 +182,15 @@ discard block |
||
182 | 182 | * add_filter( 'action_scheduler_queue_runner_flush_cache', '__return_true' ); |
183 | 183 | */ |
184 | 184 | protected function clear_caches() { |
185 | - if ( ! wp_using_ext_object_cache() || apply_filters( 'action_scheduler_queue_runner_flush_cache', false ) ) { |
|
185 | + if (!wp_using_ext_object_cache() || apply_filters('action_scheduler_queue_runner_flush_cache', false)) { |
|
186 | 186 | wp_cache_flush(); |
187 | 187 | } |
188 | 188 | } |
189 | 189 | |
190 | - public function add_wp_cron_schedule( $schedules ) { |
|
190 | + public function add_wp_cron_schedule($schedules) { |
|
191 | 191 | $schedules['every_minute'] = array( |
192 | 192 | 'interval' => 60, // in seconds |
193 | - 'display' => __( 'Every minute', 'action-scheduler' ), |
|
193 | + 'display' => __('Every minute', 'action-scheduler'), |
|
194 | 194 | ); |
195 | 195 | |
196 | 196 | return $schedules; |
@@ -10,88 +10,88 @@ |
||
10 | 10 | */ |
11 | 11 | class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request { |
12 | 12 | |
13 | - /** |
|
14 | - * Data store for querying actions |
|
15 | - * |
|
16 | - * @var ActionScheduler_Store |
|
17 | - * @access protected |
|
18 | - */ |
|
19 | - protected $store; |
|
20 | - |
|
21 | - /** |
|
22 | - * Prefix for ajax hooks |
|
23 | - * |
|
24 | - * @var string |
|
25 | - * @access protected |
|
26 | - */ |
|
27 | - protected $prefix = 'as'; |
|
28 | - |
|
29 | - /** |
|
30 | - * Action for ajax hooks |
|
31 | - * |
|
32 | - * @var string |
|
33 | - * @access protected |
|
34 | - */ |
|
35 | - protected $action = 'async_request_queue_runner'; |
|
36 | - |
|
37 | - /** |
|
38 | - * Initiate new async request |
|
39 | - */ |
|
40 | - public function __construct( ActionScheduler_Store $store ) { |
|
41 | - parent::__construct(); |
|
42 | - $this->store = $store; |
|
43 | - } |
|
44 | - |
|
45 | - /** |
|
46 | - * Handle async requests |
|
47 | - * |
|
48 | - * Run a queue, and maybe dispatch another async request to run another queue |
|
49 | - * if there are still pending actions after completing a queue in this request. |
|
50 | - */ |
|
51 | - protected function handle() { |
|
52 | - do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
53 | - |
|
54 | - $sleep_seconds = $this->get_sleep_seconds(); |
|
55 | - |
|
56 | - if ( $sleep_seconds ) { |
|
57 | - sleep( $sleep_seconds ); |
|
58 | - } |
|
59 | - |
|
60 | - $this->maybe_dispatch(); |
|
61 | - } |
|
62 | - |
|
63 | - /** |
|
64 | - * If the async request runner is needed and allowed to run, dispatch a request. |
|
65 | - */ |
|
66 | - public function maybe_dispatch() { |
|
67 | - if ( ! $this->allow() ) { |
|
68 | - return; |
|
69 | - } |
|
70 | - |
|
71 | - $this->dispatch(); |
|
72 | - ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request(); |
|
73 | - } |
|
74 | - |
|
75 | - /** |
|
76 | - * Only allow async requests when needed. |
|
77 | - * |
|
78 | - * Also allow 3rd party code to disable running actions via async requests. |
|
79 | - */ |
|
80 | - protected function allow() { |
|
81 | - |
|
82 | - if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { |
|
83 | - $allow = false; |
|
84 | - } else { |
|
85 | - $allow = true; |
|
86 | - } |
|
87 | - |
|
88 | - return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); |
|
89 | - } |
|
90 | - |
|
91 | - /** |
|
92 | - * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. |
|
93 | - */ |
|
94 | - protected function get_sleep_seconds() { |
|
95 | - return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); |
|
96 | - } |
|
13 | + /** |
|
14 | + * Data store for querying actions |
|
15 | + * |
|
16 | + * @var ActionScheduler_Store |
|
17 | + * @access protected |
|
18 | + */ |
|
19 | + protected $store; |
|
20 | + |
|
21 | + /** |
|
22 | + * Prefix for ajax hooks |
|
23 | + * |
|
24 | + * @var string |
|
25 | + * @access protected |
|
26 | + */ |
|
27 | + protected $prefix = 'as'; |
|
28 | + |
|
29 | + /** |
|
30 | + * Action for ajax hooks |
|
31 | + * |
|
32 | + * @var string |
|
33 | + * @access protected |
|
34 | + */ |
|
35 | + protected $action = 'async_request_queue_runner'; |
|
36 | + |
|
37 | + /** |
|
38 | + * Initiate new async request |
|
39 | + */ |
|
40 | + public function __construct( ActionScheduler_Store $store ) { |
|
41 | + parent::__construct(); |
|
42 | + $this->store = $store; |
|
43 | + } |
|
44 | + |
|
45 | + /** |
|
46 | + * Handle async requests |
|
47 | + * |
|
48 | + * Run a queue, and maybe dispatch another async request to run another queue |
|
49 | + * if there are still pending actions after completing a queue in this request. |
|
50 | + */ |
|
51 | + protected function handle() { |
|
52 | + do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
53 | + |
|
54 | + $sleep_seconds = $this->get_sleep_seconds(); |
|
55 | + |
|
56 | + if ( $sleep_seconds ) { |
|
57 | + sleep( $sleep_seconds ); |
|
58 | + } |
|
59 | + |
|
60 | + $this->maybe_dispatch(); |
|
61 | + } |
|
62 | + |
|
63 | + /** |
|
64 | + * If the async request runner is needed and allowed to run, dispatch a request. |
|
65 | + */ |
|
66 | + public function maybe_dispatch() { |
|
67 | + if ( ! $this->allow() ) { |
|
68 | + return; |
|
69 | + } |
|
70 | + |
|
71 | + $this->dispatch(); |
|
72 | + ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request(); |
|
73 | + } |
|
74 | + |
|
75 | + /** |
|
76 | + * Only allow async requests when needed. |
|
77 | + * |
|
78 | + * Also allow 3rd party code to disable running actions via async requests. |
|
79 | + */ |
|
80 | + protected function allow() { |
|
81 | + |
|
82 | + if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { |
|
83 | + $allow = false; |
|
84 | + } else { |
|
85 | + $allow = true; |
|
86 | + } |
|
87 | + |
|
88 | + return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); |
|
89 | + } |
|
90 | + |
|
91 | + /** |
|
92 | + * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. |
|
93 | + */ |
|
94 | + protected function get_sleep_seconds() { |
|
95 | + return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); |
|
96 | + } |
|
97 | 97 | } |
@@ -3,7 +3,7 @@ discard block |
||
3 | 3 | * ActionScheduler_AsyncRequest_QueueRunner |
4 | 4 | */ |
5 | 5 | |
6 | -defined( 'ABSPATH' ) || exit; |
|
6 | +defined('ABSPATH') || exit; |
|
7 | 7 | |
8 | 8 | /** |
9 | 9 | * ActionScheduler_AsyncRequest_QueueRunner class. |
@@ -37,7 +37,7 @@ discard block |
||
37 | 37 | /** |
38 | 38 | * Initiate new async request |
39 | 39 | */ |
40 | - public function __construct( ActionScheduler_Store $store ) { |
|
40 | + public function __construct(ActionScheduler_Store $store) { |
|
41 | 41 | parent::__construct(); |
42 | 42 | $this->store = $store; |
43 | 43 | } |
@@ -49,12 +49,12 @@ discard block |
||
49 | 49 | * if there are still pending actions after completing a queue in this request. |
50 | 50 | */ |
51 | 51 | protected function handle() { |
52 | - do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
52 | + do_action('action_scheduler_run_queue', 'Async Request'); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
53 | 53 | |
54 | 54 | $sleep_seconds = $this->get_sleep_seconds(); |
55 | 55 | |
56 | - if ( $sleep_seconds ) { |
|
57 | - sleep( $sleep_seconds ); |
|
56 | + if ($sleep_seconds) { |
|
57 | + sleep($sleep_seconds); |
|
58 | 58 | } |
59 | 59 | |
60 | 60 | $this->maybe_dispatch(); |
@@ -64,7 +64,7 @@ discard block |
||
64 | 64 | * If the async request runner is needed and allowed to run, dispatch a request. |
65 | 65 | */ |
66 | 66 | public function maybe_dispatch() { |
67 | - if ( ! $this->allow() ) { |
|
67 | + if (!$this->allow()) { |
|
68 | 68 | return; |
69 | 69 | } |
70 | 70 | |
@@ -79,19 +79,19 @@ discard block |
||
79 | 79 | */ |
80 | 80 | protected function allow() { |
81 | 81 | |
82 | - if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { |
|
82 | + if (!has_action('action_scheduler_run_queue') || ActionScheduler::runner()->has_maximum_concurrent_batches() || !$this->store->has_pending_actions_due()) { |
|
83 | 83 | $allow = false; |
84 | 84 | } else { |
85 | 85 | $allow = true; |
86 | 86 | } |
87 | 87 | |
88 | - return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); |
|
88 | + return apply_filters('action_scheduler_allow_async_request_runner', $allow); |
|
89 | 89 | } |
90 | 90 | |
91 | 91 | /** |
92 | 92 | * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. |
93 | 93 | */ |
94 | 94 | protected function get_sleep_seconds() { |
95 | - return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); |
|
95 | + return apply_filters('action_scheduler_async_request_sleep_seconds', 5, $this); |
|
96 | 96 | } |
97 | 97 | } |
@@ -7,109 +7,109 @@ |
||
7 | 7 | */ |
8 | 8 | class ActionScheduler_WPCommentCleaner { |
9 | 9 | |
10 | - /** |
|
11 | - * Post migration hook used to cleanup the WP comment table. |
|
12 | - * |
|
13 | - * @var string |
|
14 | - */ |
|
15 | - protected static $cleanup_hook = 'action_scheduler/cleanup_wp_comment_logs'; |
|
16 | - |
|
17 | - /** |
|
18 | - * An instance of the ActionScheduler_wpCommentLogger class to interact with the comments table. |
|
19 | - * |
|
20 | - * This instance should only be used as an interface. It should not be initialized. |
|
21 | - * |
|
22 | - * @var ActionScheduler_wpCommentLogger |
|
23 | - */ |
|
24 | - protected static $wp_comment_logger = null; |
|
25 | - |
|
26 | - /** |
|
27 | - * The key used to store the cached value of whether there are logs in the WP comment table. |
|
28 | - * |
|
29 | - * @var string |
|
30 | - */ |
|
31 | - protected static $has_logs_option_key = 'as_has_wp_comment_logs'; |
|
32 | - |
|
33 | - /** |
|
34 | - * Initialize the class and attach callbacks. |
|
35 | - */ |
|
36 | - public static function init() { |
|
37 | - if ( empty( self::$wp_comment_logger ) ) { |
|
38 | - self::$wp_comment_logger = new ActionScheduler_wpCommentLogger(); |
|
39 | - } |
|
40 | - |
|
41 | - add_action( self::$cleanup_hook, array( __CLASS__, 'delete_all_action_comments' ) ); |
|
42 | - |
|
43 | - // While there are orphaned logs left in the comments table, we need to attach the callbacks which filter comment counts. |
|
44 | - add_action( 'pre_get_comments', array( self::$wp_comment_logger, 'filter_comment_queries' ), 10, 1 ); |
|
45 | - add_action( 'wp_count_comments', array( self::$wp_comment_logger, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs |
|
46 | - add_action( 'comment_feed_where', array( self::$wp_comment_logger, 'filter_comment_feed' ), 10, 2 ); |
|
47 | - |
|
48 | - // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen |
|
49 | - add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) ); |
|
50 | - add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) ); |
|
51 | - } |
|
52 | - |
|
53 | - /** |
|
54 | - * Determines if there are log entries in the wp comments table. |
|
55 | - * |
|
56 | - * Uses the flag set on migration completion set by @see self::maybe_schedule_cleanup(). |
|
57 | - * |
|
58 | - * @return boolean Whether there are scheduled action comments in the comments table. |
|
59 | - */ |
|
60 | - public static function has_logs() { |
|
61 | - return 'yes' === get_option( self::$has_logs_option_key ); |
|
62 | - } |
|
63 | - |
|
64 | - /** |
|
65 | - * Schedules the WP Post comment table cleanup to run in 6 months if it's not already scheduled. |
|
66 | - * Attached to the migration complete hook 'action_scheduler/migration_complete'. |
|
67 | - */ |
|
68 | - public static function maybe_schedule_cleanup() { |
|
69 | - if ( (bool) get_comments( array( 'type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids' ) ) ) { |
|
70 | - update_option( self::$has_logs_option_key, 'yes' ); |
|
71 | - |
|
72 | - if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) { |
|
73 | - as_schedule_single_action( gmdate( 'U' ) + ( 6 * MONTH_IN_SECONDS ), self::$cleanup_hook ); |
|
74 | - } |
|
75 | - } |
|
76 | - } |
|
77 | - |
|
78 | - /** |
|
79 | - * Delete all action comments from the WP Comments table. |
|
80 | - */ |
|
81 | - public static function delete_all_action_comments() { |
|
82 | - global $wpdb; |
|
83 | - $wpdb->delete( $wpdb->comments, array( 'comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT ) ); |
|
84 | - delete_option( self::$has_logs_option_key ); |
|
85 | - } |
|
86 | - |
|
87 | - /** |
|
88 | - * Registers admin notices about the orphaned action logs. |
|
89 | - */ |
|
90 | - public static function register_admin_notice() { |
|
91 | - add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) ); |
|
92 | - } |
|
10 | + /** |
|
11 | + * Post migration hook used to cleanup the WP comment table. |
|
12 | + * |
|
13 | + * @var string |
|
14 | + */ |
|
15 | + protected static $cleanup_hook = 'action_scheduler/cleanup_wp_comment_logs'; |
|
16 | + |
|
17 | + /** |
|
18 | + * An instance of the ActionScheduler_wpCommentLogger class to interact with the comments table. |
|
19 | + * |
|
20 | + * This instance should only be used as an interface. It should not be initialized. |
|
21 | + * |
|
22 | + * @var ActionScheduler_wpCommentLogger |
|
23 | + */ |
|
24 | + protected static $wp_comment_logger = null; |
|
25 | + |
|
26 | + /** |
|
27 | + * The key used to store the cached value of whether there are logs in the WP comment table. |
|
28 | + * |
|
29 | + * @var string |
|
30 | + */ |
|
31 | + protected static $has_logs_option_key = 'as_has_wp_comment_logs'; |
|
32 | + |
|
33 | + /** |
|
34 | + * Initialize the class and attach callbacks. |
|
35 | + */ |
|
36 | + public static function init() { |
|
37 | + if ( empty( self::$wp_comment_logger ) ) { |
|
38 | + self::$wp_comment_logger = new ActionScheduler_wpCommentLogger(); |
|
39 | + } |
|
40 | + |
|
41 | + add_action( self::$cleanup_hook, array( __CLASS__, 'delete_all_action_comments' ) ); |
|
42 | + |
|
43 | + // While there are orphaned logs left in the comments table, we need to attach the callbacks which filter comment counts. |
|
44 | + add_action( 'pre_get_comments', array( self::$wp_comment_logger, 'filter_comment_queries' ), 10, 1 ); |
|
45 | + add_action( 'wp_count_comments', array( self::$wp_comment_logger, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs |
|
46 | + add_action( 'comment_feed_where', array( self::$wp_comment_logger, 'filter_comment_feed' ), 10, 2 ); |
|
47 | + |
|
48 | + // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen |
|
49 | + add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) ); |
|
50 | + add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) ); |
|
51 | + } |
|
52 | + |
|
53 | + /** |
|
54 | + * Determines if there are log entries in the wp comments table. |
|
55 | + * |
|
56 | + * Uses the flag set on migration completion set by @see self::maybe_schedule_cleanup(). |
|
57 | + * |
|
58 | + * @return boolean Whether there are scheduled action comments in the comments table. |
|
59 | + */ |
|
60 | + public static function has_logs() { |
|
61 | + return 'yes' === get_option( self::$has_logs_option_key ); |
|
62 | + } |
|
63 | + |
|
64 | + /** |
|
65 | + * Schedules the WP Post comment table cleanup to run in 6 months if it's not already scheduled. |
|
66 | + * Attached to the migration complete hook 'action_scheduler/migration_complete'. |
|
67 | + */ |
|
68 | + public static function maybe_schedule_cleanup() { |
|
69 | + if ( (bool) get_comments( array( 'type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids' ) ) ) { |
|
70 | + update_option( self::$has_logs_option_key, 'yes' ); |
|
71 | + |
|
72 | + if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) { |
|
73 | + as_schedule_single_action( gmdate( 'U' ) + ( 6 * MONTH_IN_SECONDS ), self::$cleanup_hook ); |
|
74 | + } |
|
75 | + } |
|
76 | + } |
|
77 | + |
|
78 | + /** |
|
79 | + * Delete all action comments from the WP Comments table. |
|
80 | + */ |
|
81 | + public static function delete_all_action_comments() { |
|
82 | + global $wpdb; |
|
83 | + $wpdb->delete( $wpdb->comments, array( 'comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT ) ); |
|
84 | + delete_option( self::$has_logs_option_key ); |
|
85 | + } |
|
86 | + |
|
87 | + /** |
|
88 | + * Registers admin notices about the orphaned action logs. |
|
89 | + */ |
|
90 | + public static function register_admin_notice() { |
|
91 | + add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) ); |
|
92 | + } |
|
93 | 93 | |
94 | - /** |
|
95 | - * Prints details about the orphaned action logs and includes information on where to learn more. |
|
96 | - */ |
|
97 | - public static function print_admin_notice() { |
|
98 | - $next_cleanup_message = ''; |
|
99 | - $next_scheduled_cleanup_hook = as_next_scheduled_action( self::$cleanup_hook ); |
|
100 | - |
|
101 | - if ( $next_scheduled_cleanup_hook ) { |
|
102 | - /* translators: %s: date interval */ |
|
103 | - $next_cleanup_message = sprintf( __( 'This data will be deleted in %s.', 'action-scheduler' ), human_time_diff( gmdate( 'U' ), $next_scheduled_cleanup_hook ) ); |
|
104 | - } |
|
105 | - |
|
106 | - $notice = sprintf( |
|
107 | - /* translators: 1: next cleanup message 2: github issue URL */ |
|
108 | - __( 'Action Scheduler has migrated data to custom tables; however, orphaned log entries exist in the WordPress Comments table. %1$s <a href="%2$s">Learn more »</a>', 'action-scheduler' ), |
|
109 | - $next_cleanup_message, |
|
110 | - 'https://github.com/woocommerce/action-scheduler/issues/368' |
|
111 | - ); |
|
112 | - |
|
113 | - echo '<div class="notice notice-warning"><p>' . wp_kses_post( $notice ) . '</p></div>'; |
|
114 | - } |
|
94 | + /** |
|
95 | + * Prints details about the orphaned action logs and includes information on where to learn more. |
|
96 | + */ |
|
97 | + public static function print_admin_notice() { |
|
98 | + $next_cleanup_message = ''; |
|
99 | + $next_scheduled_cleanup_hook = as_next_scheduled_action( self::$cleanup_hook ); |
|
100 | + |
|
101 | + if ( $next_scheduled_cleanup_hook ) { |
|
102 | + /* translators: %s: date interval */ |
|
103 | + $next_cleanup_message = sprintf( __( 'This data will be deleted in %s.', 'action-scheduler' ), human_time_diff( gmdate( 'U' ), $next_scheduled_cleanup_hook ) ); |
|
104 | + } |
|
105 | + |
|
106 | + $notice = sprintf( |
|
107 | + /* translators: 1: next cleanup message 2: github issue URL */ |
|
108 | + __( 'Action Scheduler has migrated data to custom tables; however, orphaned log entries exist in the WordPress Comments table. %1$s <a href="%2$s">Learn more »</a>', 'action-scheduler' ), |
|
109 | + $next_cleanup_message, |
|
110 | + 'https://github.com/woocommerce/action-scheduler/issues/368' |
|
111 | + ); |
|
112 | + |
|
113 | + echo '<div class="notice notice-warning"><p>' . wp_kses_post( $notice ) . '</p></div>'; |
|
114 | + } |
|
115 | 115 | } |
@@ -34,20 +34,20 @@ discard block |
||
34 | 34 | * Initialize the class and attach callbacks. |
35 | 35 | */ |
36 | 36 | public static function init() { |
37 | - if ( empty( self::$wp_comment_logger ) ) { |
|
37 | + if (empty(self::$wp_comment_logger)) { |
|
38 | 38 | self::$wp_comment_logger = new ActionScheduler_wpCommentLogger(); |
39 | 39 | } |
40 | 40 | |
41 | - add_action( self::$cleanup_hook, array( __CLASS__, 'delete_all_action_comments' ) ); |
|
41 | + add_action(self::$cleanup_hook, array(__CLASS__, 'delete_all_action_comments')); |
|
42 | 42 | |
43 | 43 | // While there are orphaned logs left in the comments table, we need to attach the callbacks which filter comment counts. |
44 | - add_action( 'pre_get_comments', array( self::$wp_comment_logger, 'filter_comment_queries' ), 10, 1 ); |
|
45 | - add_action( 'wp_count_comments', array( self::$wp_comment_logger, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs |
|
46 | - add_action( 'comment_feed_where', array( self::$wp_comment_logger, 'filter_comment_feed' ), 10, 2 ); |
|
44 | + add_action('pre_get_comments', array(self::$wp_comment_logger, 'filter_comment_queries'), 10, 1); |
|
45 | + add_action('wp_count_comments', array(self::$wp_comment_logger, 'filter_comment_count'), 20, 2); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs |
|
46 | + add_action('comment_feed_where', array(self::$wp_comment_logger, 'filter_comment_feed'), 10, 2); |
|
47 | 47 | |
48 | 48 | // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen |
49 | - add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) ); |
|
50 | - add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) ); |
|
49 | + add_action('load-tools_page_action-scheduler', array(__CLASS__, 'register_admin_notice')); |
|
50 | + add_action('load-woocommerce_page_wc-status', array(__CLASS__, 'register_admin_notice')); |
|
51 | 51 | } |
52 | 52 | |
53 | 53 | /** |
@@ -58,7 +58,7 @@ discard block |
||
58 | 58 | * @return boolean Whether there are scheduled action comments in the comments table. |
59 | 59 | */ |
60 | 60 | public static function has_logs() { |
61 | - return 'yes' === get_option( self::$has_logs_option_key ); |
|
61 | + return 'yes' === get_option(self::$has_logs_option_key); |
|
62 | 62 | } |
63 | 63 | |
64 | 64 | /** |
@@ -66,11 +66,11 @@ discard block |
||
66 | 66 | * Attached to the migration complete hook 'action_scheduler/migration_complete'. |
67 | 67 | */ |
68 | 68 | public static function maybe_schedule_cleanup() { |
69 | - if ( (bool) get_comments( array( 'type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids' ) ) ) { |
|
70 | - update_option( self::$has_logs_option_key, 'yes' ); |
|
69 | + if ((bool) get_comments(array('type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids'))) { |
|
70 | + update_option(self::$has_logs_option_key, 'yes'); |
|
71 | 71 | |
72 | - if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) { |
|
73 | - as_schedule_single_action( gmdate( 'U' ) + ( 6 * MONTH_IN_SECONDS ), self::$cleanup_hook ); |
|
72 | + if (!as_next_scheduled_action(self::$cleanup_hook)) { |
|
73 | + as_schedule_single_action(gmdate('U') + (6 * MONTH_IN_SECONDS), self::$cleanup_hook); |
|
74 | 74 | } |
75 | 75 | } |
76 | 76 | } |
@@ -80,15 +80,15 @@ discard block |
||
80 | 80 | */ |
81 | 81 | public static function delete_all_action_comments() { |
82 | 82 | global $wpdb; |
83 | - $wpdb->delete( $wpdb->comments, array( 'comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT ) ); |
|
84 | - delete_option( self::$has_logs_option_key ); |
|
83 | + $wpdb->delete($wpdb->comments, array('comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT)); |
|
84 | + delete_option(self::$has_logs_option_key); |
|
85 | 85 | } |
86 | 86 | |
87 | 87 | /** |
88 | 88 | * Registers admin notices about the orphaned action logs. |
89 | 89 | */ |
90 | 90 | public static function register_admin_notice() { |
91 | - add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) ); |
|
91 | + add_action('admin_notices', array(__CLASS__, 'print_admin_notice')); |
|
92 | 92 | } |
93 | 93 | |
94 | 94 | /** |
@@ -96,20 +96,20 @@ discard block |
||
96 | 96 | */ |
97 | 97 | public static function print_admin_notice() { |
98 | 98 | $next_cleanup_message = ''; |
99 | - $next_scheduled_cleanup_hook = as_next_scheduled_action( self::$cleanup_hook ); |
|
99 | + $next_scheduled_cleanup_hook = as_next_scheduled_action(self::$cleanup_hook); |
|
100 | 100 | |
101 | - if ( $next_scheduled_cleanup_hook ) { |
|
101 | + if ($next_scheduled_cleanup_hook) { |
|
102 | 102 | /* translators: %s: date interval */ |
103 | - $next_cleanup_message = sprintf( __( 'This data will be deleted in %s.', 'action-scheduler' ), human_time_diff( gmdate( 'U' ), $next_scheduled_cleanup_hook ) ); |
|
103 | + $next_cleanup_message = sprintf(__('This data will be deleted in %s.', 'action-scheduler'), human_time_diff(gmdate('U'), $next_scheduled_cleanup_hook)); |
|
104 | 104 | } |
105 | 105 | |
106 | 106 | $notice = sprintf( |
107 | 107 | /* translators: 1: next cleanup message 2: github issue URL */ |
108 | - __( 'Action Scheduler has migrated data to custom tables; however, orphaned log entries exist in the WordPress Comments table. %1$s <a href="%2$s">Learn more »</a>', 'action-scheduler' ), |
|
108 | + __('Action Scheduler has migrated data to custom tables; however, orphaned log entries exist in the WordPress Comments table. %1$s <a href="%2$s">Learn more »</a>', 'action-scheduler'), |
|
109 | 109 | $next_cleanup_message, |
110 | 110 | 'https://github.com/woocommerce/action-scheduler/issues/368' |
111 | 111 | ); |
112 | 112 | |
113 | - echo '<div class="notice notice-warning"><p>' . wp_kses_post( $notice ) . '</p></div>'; |
|
113 | + echo '<div class="notice notice-warning"><p>' . wp_kses_post($notice) . '</p></div>'; |
|
114 | 114 | } |
115 | 115 | } |
@@ -5,12 +5,12 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_FinishedAction extends ActionScheduler_Action { |
7 | 7 | |
8 | - public function execute() { |
|
9 | - // don't execute |
|
10 | - } |
|
8 | + public function execute() { |
|
9 | + // don't execute |
|
10 | + } |
|
11 | 11 | |
12 | - public function is_finished() { |
|
13 | - return TRUE; |
|
14 | - } |
|
12 | + public function is_finished() { |
|
13 | + return TRUE; |
|
14 | + } |
|
15 | 15 | } |
16 | - |
|
17 | 16 | \ No newline at end of file |
17 | + |
|
18 | 18 | \ No newline at end of file |