A5hleyRich /
wp-queue
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace WP_Queue; |
||||||
| 4 | |||||||
| 5 | class Cron { |
||||||
| 6 | |||||||
| 7 | /** |
||||||
| 8 | * @var string |
||||||
| 9 | */ |
||||||
| 10 | protected $id; |
||||||
| 11 | |||||||
| 12 | /** |
||||||
| 13 | * @var Worker |
||||||
| 14 | */ |
||||||
| 15 | protected $worker; |
||||||
| 16 | |||||||
| 17 | /** |
||||||
| 18 | * @var int |
||||||
| 19 | */ |
||||||
| 20 | protected $interval; |
||||||
| 21 | |||||||
| 22 | /** |
||||||
| 23 | * Timestamp of when processing the queue started. |
||||||
| 24 | * |
||||||
| 25 | * @var int |
||||||
| 26 | */ |
||||||
| 27 | protected $start_time; |
||||||
| 28 | |||||||
| 29 | /** |
||||||
| 30 | * Cron constructor. |
||||||
| 31 | * |
||||||
| 32 | * @param string $id |
||||||
| 33 | * @param Worker $worker |
||||||
| 34 | * @param int $interval |
||||||
| 35 | */ |
||||||
| 36 | 1 | public function __construct( $id, $worker, $interval ) { |
|||||
| 37 | 1 | $this->id = strtolower( str_replace( '\\', '_', $id ) ); |
|||||
| 38 | 1 | $this->worker = $worker; |
|||||
| 39 | 1 | $this->interval = $interval; |
|||||
| 40 | 1 | } |
|||||
| 41 | |||||||
| 42 | /** |
||||||
| 43 | * Is the cron queue worker enabled? |
||||||
| 44 | * |
||||||
| 45 | * @return bool |
||||||
| 46 | */ |
||||||
| 47 | 1 | protected function is_enabled() { |
|||||
| 48 | 1 | if ( defined( 'DISABLE_WP_QUEUE_CRON' ) && DISABLE_WP_QUEUE_CRON ) { |
|||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||||
| 49 | return false; |
||||||
| 50 | } |
||||||
| 51 | |||||||
| 52 | 1 | return true; |
|||||
| 53 | } |
||||||
| 54 | |||||||
| 55 | /** |
||||||
| 56 | * Init cron class. |
||||||
| 57 | * |
||||||
| 58 | * @return bool |
||||||
| 59 | */ |
||||||
| 60 | 1 | public function init() { |
|||||
| 61 | 1 | if ( ! $this->is_enabled() ) { |
|||||
| 62 | return false; |
||||||
| 63 | } |
||||||
| 64 | |||||||
| 65 | 1 | add_filter( 'cron_schedules', array( $this, 'schedule_cron' ) ); |
|||||
| 66 | 1 | add_action( $this->id, array( $this, 'cron_worker' ) ); |
|||||
| 67 | |||||||
| 68 | 1 | if ( ! wp_next_scheduled( $this->id ) ) { |
|||||
| 69 | // Schedule health check |
||||||
| 70 | wp_schedule_event( time(), $this->id, $this->id ); |
||||||
|
0 ignored issues
–
show
The function
wp_schedule_event was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 71 | } |
||||||
| 72 | |||||||
| 73 | 1 | return true; |
|||||
| 74 | } |
||||||
| 75 | |||||||
| 76 | /** |
||||||
| 77 | * Add interval to cron schedules. |
||||||
| 78 | * |
||||||
| 79 | * @param array $schedules |
||||||
| 80 | * |
||||||
| 81 | * @return array |
||||||
| 82 | */ |
||||||
| 83 | public function schedule_cron( $schedules ) { |
||||||
| 84 | $schedules[ $this->id ] = array( |
||||||
| 85 | 'interval' => MINUTE_IN_SECONDS * $this->interval, |
||||||
|
0 ignored issues
–
show
|
|||||||
| 86 | 'display' => sprintf( __( 'Every %d Minutes' ), $this->interval ), |
||||||
| 87 | ); |
||||||
| 88 | |||||||
| 89 | return $schedules; |
||||||
| 90 | } |
||||||
| 91 | |||||||
| 92 | /** |
||||||
| 93 | * Process any jobs in the queue. |
||||||
| 94 | */ |
||||||
| 95 | public function cron_worker() { |
||||||
| 96 | if ( $this->is_worker_locked() ) { |
||||||
| 97 | return; |
||||||
| 98 | } |
||||||
| 99 | |||||||
| 100 | $this->start_time = time(); |
||||||
| 101 | |||||||
| 102 | $this->lock_worker(); |
||||||
| 103 | |||||||
| 104 | while ( ! $this->time_exceeded() && ! $this->memory_exceeded() ) { |
||||||
| 105 | if ( ! $this->worker->process() ) { |
||||||
| 106 | break; |
||||||
| 107 | } |
||||||
| 108 | } |
||||||
| 109 | |||||||
| 110 | $this->unlock_worker(); |
||||||
| 111 | } |
||||||
| 112 | |||||||
| 113 | /** |
||||||
| 114 | * Is the cron worker locked? |
||||||
| 115 | * |
||||||
| 116 | * @return bool |
||||||
| 117 | */ |
||||||
| 118 | protected function is_worker_locked() { |
||||||
| 119 | return (bool) get_site_transient( $this->id ); |
||||||
|
0 ignored issues
–
show
The function
get_site_transient was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 120 | } |
||||||
| 121 | |||||||
| 122 | /** |
||||||
| 123 | * Lock the cron worker. |
||||||
| 124 | */ |
||||||
| 125 | protected function lock_worker() { |
||||||
| 126 | set_site_transient( $this->id, time(), 300 ); |
||||||
|
0 ignored issues
–
show
The function
set_site_transient was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 127 | } |
||||||
| 128 | |||||||
| 129 | /** |
||||||
| 130 | * Unlock the cron worker. |
||||||
| 131 | */ |
||||||
| 132 | protected function unlock_worker() { |
||||||
| 133 | delete_site_transient( $this->id ); |
||||||
|
0 ignored issues
–
show
The function
delete_site_transient was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 134 | } |
||||||
| 135 | |||||||
| 136 | /** |
||||||
| 137 | * Memory exceeded |
||||||
| 138 | * |
||||||
| 139 | * Ensures the worker process never exceeds 80% |
||||||
| 140 | * of the maximum allowed PHP memory. |
||||||
| 141 | * |
||||||
| 142 | * @return bool |
||||||
| 143 | */ |
||||||
| 144 | protected function memory_exceeded() { |
||||||
| 145 | $memory_limit = $this->get_memory_limit() * 0.8; // 80% of max memory |
||||||
| 146 | $current_memory = memory_get_usage( true ); |
||||||
| 147 | $return = false; |
||||||
| 148 | |||||||
| 149 | if ( $current_memory >= $memory_limit ) { |
||||||
| 150 | $return = true; |
||||||
| 151 | } |
||||||
| 152 | |||||||
| 153 | return apply_filters( 'wp_queue_cron_memory_exceeded', $return ); |
||||||
| 154 | } |
||||||
| 155 | |||||||
| 156 | /** |
||||||
| 157 | * Get memory limit. |
||||||
| 158 | * |
||||||
| 159 | * @return int |
||||||
| 160 | */ |
||||||
| 161 | protected function get_memory_limit() { |
||||||
| 162 | if ( function_exists( 'ini_get' ) ) { |
||||||
| 163 | $memory_limit = ini_get( 'memory_limit' ); |
||||||
| 164 | } else { |
||||||
| 165 | $memory_limit = '256M'; |
||||||
| 166 | } |
||||||
| 167 | |||||||
| 168 | if ( ! $memory_limit || - 1 == $memory_limit ) { |
||||||
| 169 | // Unlimited, set to 1GB |
||||||
| 170 | $memory_limit = '1000M'; |
||||||
| 171 | } |
||||||
| 172 | |||||||
| 173 | return intval( $memory_limit ) * 1024 * 1024; |
||||||
| 174 | } |
||||||
| 175 | |||||||
| 176 | /** |
||||||
| 177 | * Time exceeded |
||||||
| 178 | * |
||||||
| 179 | * Ensures the worker never exceeds a sensible time limit (20s by default). |
||||||
| 180 | * A timeout limit of 30s is common on shared hosting. |
||||||
| 181 | * |
||||||
| 182 | * @return bool |
||||||
| 183 | */ |
||||||
| 184 | protected function time_exceeded() { |
||||||
| 185 | $finish = $this->start_time + apply_filters( 'wp_queue_cron_time_limit', 20 ); // 20 seconds |
||||||
| 186 | $return = false; |
||||||
| 187 | |||||||
| 188 | if ( time() >= $finish ) { |
||||||
| 189 | $return = true; |
||||||
| 190 | } |
||||||
| 191 | |||||||
| 192 | return apply_filters( 'wp_queue_cron_time_exceeded', $return ); |
||||||
| 193 | } |
||||||
| 194 | } |