PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / trunk
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score vtrunk
trunk 1.0 1.0.1 1.1 1.1.1 1.1.2 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1 2.1.1 2.1.2 2.2 2.2.1 All 69 releases
← All changes | includes/classes/Async/CachePreloader.php +102 -7 2.2trunk View file →
@@ -7,8 +7,9 @@
7 7
8 8 namespace PoweredCache\Async;
9 9
10 10 use PoweredCache\Preloader;
11 +use function PoweredCache\Utils\detect_cpu_cores;
11 12 use function PoweredCache\Utils\is_url_cached;
12 13 use \Powered_Cache_WP_Background_Process as Powered_Cache_WP_Background_Process;
13 14
14 15 /**
@@ -53,17 +54,24 @@
53 54 *
54 55 * @return mixed
55 56 */
56 57 protected function task( $item ) {
58 + // Stop early if system load is too high
59 + if ( ! $this->should_continue() ) {
60 + \PoweredCache\Utils\log( 'Preload task aborted early due to system load' );
61 + return $item;
62 + }
63 +
57 64 $this->settings = \PoweredCache\Utils\get_settings();
65 + $delay = absint( $this->settings['preload_request_interval'] ) * 1000000; // convert to microseconds
58 66
59 - \PoweredCache\Utils\log( sprintf( 'Preloading...%s', $item ) );
67 + \PoweredCache\Utils\log( sprintf( 'Preloading..: %s', $item ) );
60 68
61 69 if ( filter_var( $item, FILTER_VALIDATE_URL ) ) {
62 70
63 71 if ( ! is_url_cached( $item, false, $this->settings['gzip_compression'] ) ) {
64 72 Preloader::preload_request( $item );
65 - Preloader::wait();
73 + Preloader::wait( $delay );
66 74 }
67 75
68 76 // make the preload request by using mobile agent
69 77 if ( $this->settings['cache_mobile'] && $this->settings['cache_mobile_separate_file'] ) {
@@ -68,14 +76,14 @@
68 76 // make the preload request by using mobile agent
69 77 if ( $this->settings['cache_mobile'] && $this->settings['cache_mobile_separate_file'] ) {
70 78 if ( ! is_url_cached( $item, true, $this->settings['gzip_compression'] ) ) {
71 79 Preloader::preload_request( $item, [ 'user-agent' => Preloader::mobile_user_agent() ] );
72 - Preloader::wait();
80 + Preloader::wait( $delay );
73 81 }
74 82 }
75 83 }
76 84
77 - \PoweredCache\Utils\log( sprintf( 'Preloading completed...%s', $item ) );
85 + \PoweredCache\Utils\log( sprintf( 'Preloaded...: %s', $item ) );
78 86
79 87 return false;
80 88 }
81 89
@@ -91,9 +99,9 @@
91 99 }
92 100
93 101 /**
94 102 * Sometimes canceling a process is glitchy
95 - * Try to cancell all items in the queue up to $max_attempt
103 + * Try to cancel all items in the queue up to $max_attempt
96 104 */
97 105 public function cancel_process() {
98 106 $max_attempt = 5;
99 107 $cancelled = 0;
@@ -100,9 +108,9 @@
100 108 while ( ! parent::is_queue_empty() ) {
101 109 if ( $cancelled >= $max_attempt ) {
102 110 break;
103 111 }
104 - parent::cancel_process();
112 + parent::cancel();
105 113 $cancelled ++;
106 114 }
107 115 }
108 116
@@ -111,10 +119,97 @@
111 119 *
112 120 * @return bool
113 121 */
114 122 public function is_process_running() { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found
115 - return parent::is_process_running();
123 + return parent::is_processing();
116 124 }
125 +
126 + /**
127 + * Determine if the background process should continue.
128 + * Stops the process if server load is too high or spikes suddenly.
129 + *
130 + * @return bool
131 + */
132 + public function should_continue() {
133 + $should_continue = parent::should_continue();
134 + $halted_by_load = false;
135 +
136 + $load = function_exists( 'sys_getloadavg' )
137 + ? sys_getloadavg()
138 + : [ 0.0, 0.0, 0.0 ];
139 +
140 + $load_1min = isset( $load[0] ) ? (float) $load[0] : 0.0;
141 + $load_5min = isset( $load[1] ) ? (float) $load[1] : 0.0;
142 + $load_15min = isset( $load[2] ) ? (float) $load[2] : 0.0;
143 +
144 + // Weighted average: gives slightly more weight to short-term load.
145 + $weighted_load = ( $load_1min * 0.5 + $load_5min * 0.3 + $load_15min * 0.2 );
146 +
147 + // Consider a spike if 1min load is significantly higher than longer-term averages.
148 + $load_spike_detected = ( $load_1min > $load_5min * 2 || $load_5min > $load_15min * 2 );
149 +
150 + // Fallback max load threshold
151 + $default_max_load = 16.0;
152 +
153 + /**
154 + * Filter the max allowed server load before preloading pauses.
155 + *
156 + * @hook powered_cache_preloader_max_server_load
157 + *
158 + * @param {float} $default_max_load Default load threshold.
159 + * @param {array} $load [1min, 5min, 15min] load averages.
160 + *
161 + * @return {float} Maximum allowed server load before preloading pauses.
162 + * @since 3.6
163 + */
164 + $max_allowed_load = apply_filters(
165 + 'powered_cache_preloader_max_server_load',
166 + $default_max_load,
167 + $load
168 + );
169 +
170 + // Allow setting a custom maximum server load threshold.
171 + if ( defined( 'POWERED_CACHE_PRELOADER_MAX_SERVER_LOAD' ) && is_numeric( POWERED_CACHE_PRELOADER_MAX_SERVER_LOAD ) ) {
172 + $max_allowed_load = (float) POWERED_CACHE_PRELOADER_MAX_SERVER_LOAD;
173 + }
174 +
175 + if ( $should_continue && ( $weighted_load > $max_allowed_load || $load_spike_detected ) ) {
176 + \PoweredCache\Utils\log(
177 + sprintf(
178 + 'Preload paused: server load too high or spike detected (1min: %.2f, 5min: %.2f, 15min: %.2f, weighted: %.2f, threshold: %.2f)',
179 + $load_1min,
180 + $load_5min,
181 + $load_15min,
182 + $weighted_load,
183 + $max_allowed_load
184 + )
185 + );
186 + $should_continue = false;
187 + $halted_by_load = true;
188 + }
189 +
190 + /**
191 + * Allow complete control over continuation logic.
192 + *
193 + * @hook powered_cache_preloader_should_continue
194 + *
195 + * @param bool $should_continue Whether to continue processing.
196 + * @param bool $halted_by_load True if we halted due to load.
197 + * @param array $load [1min, 5min, 15min] load averages.
198 + * @param float $max_allowed_load Final load limit used for decision.
199 + *
200 + * @return bool Whether to continue processing.
201 + * @since 3.6
202 + */
203 + return (bool) apply_filters(
204 + 'powered_cache_preloader_should_continue',
205 + $should_continue,
206 + $halted_by_load,
207 + $load,
208 + $max_allowed_load
209 + );
210 + }
211 +
117 212
118 213 /**
119 214 * Return an instance of the current class
120 215 *