diff --git a/changelog.txt b/changelog.txt index 6c5636e..d6e87be 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ += v21.08.11 (2022-05-30) = +- Fixed: Avoid calling Filesystem::close_buffer() if a process involved accessing a disk. +- Fixed: Removed handling stale cache on shutdown. +- Added: Garbage Collector Status -> Cleanup Stale Cache. +- Improved: Collected stale cache will be handled by Garbage Collector. + = v21.08.10 (2022-05-20) = - Changed: Disable "CHUNKCACHEDIR" by default. Let's users choose it depending on their hosting environment. diff --git a/dist/docket-cache.zip b/dist/docket-cache.zip index af44ed4..9a11e8d 100644 Binary files a/dist/docket-cache.zip and b/dist/docket-cache.zip differ diff --git a/docket-cache.php b/docket-cache.php index d5ee916..f868baf 100644 --- a/docket-cache.php +++ b/docket-cache.php @@ -12,8 +12,8 @@ * @wordpress-plugin * Plugin Name: Docket Cache * Plugin URI: https://docketcache.com/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash - * Version: 21.08.10 - * VerPrev: 21.08.09 + * Version: 21.08.11 + * VerPrev: 21.08.10 * Description: A persistent object cache stored as a plain PHP code, accelerates caching with OPcache backend. * GitHub Plugin URI: https://github.com/nawawi/docket-cache * Author: Nawawi Jamili diff --git a/includes/admin/config.php b/includes/admin/config.php index af291c3..9f5aea1 100644 --- a/includes/admin/config.php +++ b/includes/admin/config.php @@ -470,18 +470,6 @@ - - tooltip('chunkcachedir'); ?> - - config_select_bool('chunkcachedir'); ?> - - - - tooltip('flush_stalecache'); ?> - - config_select_bool('flush_stalecache'); ?> - - tooltip('maxfile'); ?> @@ -512,7 +500,7 @@ - tooltip('maxsize_disk'); ?> + tooltip('maxsize_disk'); ?> + + tooltip('chunkcachedir'); ?> + + config_select_bool('chunkcachedir'); ?> + + + + tooltip('flush_stalecache'); ?> + + config_select_bool('flush_stalecache'); ?> + + diff --git a/includes/cache.php b/includes/cache.php index 77a8276..71a8d8e 100644 --- a/includes/cache.php +++ b/includes/cache.php @@ -174,6 +174,13 @@ class WP_Object_Cache */ private $wp_start_timestamp = 0; + /** + * Stalecache status. + * + * @var bool + */ + private $is_stalecache = false; + /** * List of stale cache to remove. * @@ -353,7 +360,7 @@ public function set($key, $data, $group = 'default', $expire = 0) } // from invalidate cache - if ($this->cf()->is_dctrue('FLUSH_STALECACHE')) { + if ($this->is_stalecache) { $this->dc_stalecache_filter($key, $group); } @@ -782,7 +789,7 @@ private function flush_filtered_groups($hook, $args) $keys = array_unique($keys); foreach ($keys as $key) { $this->delete($key, $group); - $this->dc_log('flush', 'internalproc-'.$this->item_hash(__FUNCTION__), $group.':'.$key); + $this->dc_log('flush', '000000000000-'.$this->item_hash(__FUNCTION__), $group.':'.$key); } } @@ -833,7 +840,7 @@ private function maybe_expire($group, $expire = 0, $key = '') } } - // if 0 let gc handle it by comparing file mtime. + // if 0 let's gc handle it by comparing file mtime. return $expire; } @@ -1019,22 +1026,22 @@ private function dc_flush() $dir = $this->cache_path; $is_timeout = false; $cnt = $this->fs()->cachedir_flush($dir, false, $is_timeout); - $logroup = $this->item_hash(__FUNCTION__); + $logkey = '000000000000-'.$this->item_hash(__FUNCTION__); if ($is_timeout) { - $this->dc_log('err', 'internalproc-'.$logroup, 'Process aborted. Reached maximum execution time. Total cache flushed: '.$cnt); + $this->dc_log('err', $logkey, 'Process aborted. Reached maximum execution time. Total cache flushed: '.$cnt); return false; } if (false === $cnt) { - $this->dc_log('err', 'internalproc-'.$logroup, 'Cache could not be flushed'); + $this->dc_log('err', $logkey, 'Cache could not be flushed'); return false; } if ($cnt > 0) { - $this->dc_log('flush', 'internalproc-'.$logroup, 'Total cache flushed: '.$cnt); + $this->dc_log('flush', $logkey, 'Total cache flushed: '.$cnt); } return true; @@ -1121,7 +1128,6 @@ public function dc_remove_group_match($group) if ($grp === substr($match, 0, \strlen($grp))) { $this->fs()->unlink($fx, true); $this->dc_log('flush', $this->get_item_hash($fx), $match.':*'); - unset($this->cache[$match]); ++$total; @@ -1131,7 +1137,6 @@ public function dc_remove_group_match($group) if ($group === substr($match, 0, \strlen($group))) { $this->fs()->unlink($fx, true); $this->dc_log('flush', $this->get_item_hash($fx), $match.':*'); - unset($this->cache[$match]); ++$total; @@ -1189,130 +1194,25 @@ private function dc_stalecache_filter($key, $group) */ public function add_stalecache($lists) { - if ($this->cf()->is_dctrue('FLUSH_STALECACHE') && !empty($lists) && \is_array($lists)) { + if ($this->is_stalecache && !empty($lists) && \is_array($lists)) { $this->stalecache_list = array_merge($this->stalecache_list, $lists); } } - /** - * flush_stalecache. - */ - private function flush_stalecache() - { - $total = 0; - if (!$this->fs()->is_docketcachedir($this->cache_path)) { - return $total; - } - - $slowdown = 0; - $pattern = '@^([a-z0-9]{12})\-([a-z0-9]{12})\.php$@'; - foreach ($this->fs()->scanfiles($this->cache_path, null, $pattern) as $object) { - if ($object->isFile()) { - $fx = $object->getPathName(); - $logprefix = $this->get_item_hash($fx); - - $data = $this->fs()->cache_get($fx); - if (!empty($data) && !empty($data['key']) && !empty($data['group'])) { - unset($data['data']); - - foreach ($this->stalecache_list as $id => $key) { - $do_flush = false; - - if (false !== strpos($data['key'], 'wc_cache_') && 'wc_cache:' === substr($key, 0, 9) && preg_match('@^wc_cache_([0-9\. ]+)_.*@', $data['key'], $mm)) { - list($prefix, $group, $usec) = explode(':', $key); - if ($usec === $mm[1]) { - $do_flush = true; - } else { - $usec1 = nwdcx_microtimetofloat($usec); - $usec2 = nwdcx_microtimetofloat($mm[1]); - if ($usec1 > $usec2) { - $do_flush = true; - } - } - - // group = from cache file, key = list key - } elseif (false !== strpos($data['group'], 'docketcache-post-') && false !== strpos($key, 'docketcache-post-')) { - if ($key === $data['group']) { - $do_flush = true; - } else { - $usec1 = str_replace('docketcache-post-', '', $key); - $usec2 = str_replace('docketcache-post-', '', $data['group']); - if ($usec1 > $usec2) { - $do_flush = true; - } - } - } elseif (false !== strpos($key, 'last_changed:') && @preg_match('@(.*):([a-z0-9]{32}):([0-9\. ]+)$@', $data['key'], $mm)) { - list($prefix, $group, $usec) = explode(':', $key); - if ($group === $data['group']) { - $usec1 = nwdcx_microtimetofloat($usec); - $usec2 = nwdcx_microtimetofloat($mm[3]); - if ($usec1 > $usec2) { - $do_flush = true; - } - } - } elseif (false !== strpos($key, 'after:') && @preg_match('@(.*):([a-z0-9]{32}):([0-9\. ]+)$@', $data['key'], $mm)) { - list($prefix, $group, $usec, $abc) = explode(':', $key); - if ($group === $data['group'] && $abc === $mm[1]) { - $usec1 = nwdcx_microtimetofloat($usec); - $usec2 = nwdcx_microtimetofloat($mm[3]); - if ($usec1 > $usec2) { - $do_flush = true; - } - } - } - - if ($do_flush) { - $nwdcx_suppresserrors = nwdcx_suppresserrors(true); - // use native unlink since it is a junk file. - if (@unlink($fx)) { - $this->dc_log('flush', $logprefix, 'stale-cache: '.$data['group'].':'.$data['key']); - } - nwdcx_suppresserrors($nwdcx_suppresserrors); - break; // found and break foreach2 - } - - if ($this->max_execution_time > 0 && (microtime(true) - $this->wp_start_timestamp) > $this->max_execution_time) { - break 2; // stop scanfiles - } - - if ($slowdown > 10) { - $slowdown = 0; - usleep(1000); - } - } // foreach2 - } - unset($data); - } // foreach1 - - if ($slowdown > 10) { - $slowdown = 0; - usleep(5000); - } - - ++$slowdown; - - if ($this->max_execution_time > 0 && (microtime(true) - $this->wp_start_timestamp) > $this->max_execution_time) { - break; - } - } - - return $total; - } - /** * dc_get. */ private function dc_get($key, $group, $is_raw = false) { $file = $this->get_file_path($key, $group); - $index = $this->get_item_hash($file); + $logkey = $this->get_item_hash($file); $data = $this->fs()->cache_get($file); if (false === $data) { if (!$this->skip_stats($group)) { ++$this->cache_misses; - $this->dc_log('miss', $index, $group.':'.$key); + $this->dc_log('miss', $logkey, $group.':'.$key); } return false; @@ -1320,7 +1220,7 @@ private function dc_get($key, $group, $is_raw = false) $is_timeout = false; if (!empty($data['timeout']) && $this->fs()->valid_timestamp($data['timeout']) && time() >= $data['timeout']) { - $this->dc_log('exp', $this->get_item_hash($file), $group.':'.$key); + $this->dc_log('exp', $logkey, $group.':'.$key); $this->fs()->unlink($file, false); $is_timeout = true; } @@ -1329,14 +1229,14 @@ private function dc_get($key, $group, $is_raw = false) if (!$is_timeout && !empty($this->cache_maxttl) && !empty($data['timestamp']) && $this->fs()->valid_timestamp($data['timestamp'])) { $maxttl = time() - $this->cache_maxttl; if ($data['timestamp'] < $maxttl) { - $this->dc_log('exp', $this->get_item_hash($file), $group.':'.$key); + $this->dc_log('exp', $logkey, $group.':'.$key); $this->fs()->unlink($file, true); // true = delete it instead of truncate } } if (!$this->skip_stats($group)) { ++$this->cache_hits; - $this->dc_log('hit', $index, $group.':'.$key); + $this->dc_log('hit', $logkey, $group.':'.$key); } // If the transient does not exist, does not have a value, or has expired, then the return value will be false. @@ -1365,11 +1265,12 @@ private function dc_get($key, $group, $is_raw = false) */ private function dc_code($file, $arr) { - $fname = $this->get_item_hash($file); + $logkey = $this->get_item_hash($file); + $logpref = __FUNCTION__.'():'; $data = $this->fs()->export_var($arr, $error); if (false === $data) { - $this->dc_log('err', $fname, 'Failed to export var: '.$error); + $this->dc_log('err', $logkey, $logpref.' Failed to export var -> '.$error); return false; } @@ -1382,7 +1283,7 @@ private function dc_code($file, $arr) } if (-1 === $stat) { - $this->dc_log('err', $fname, 'Failed to write'); + $this->dc_log('err', $logkey, $logpref.' Failed to write'); return false; } @@ -1402,12 +1303,13 @@ private function dc_save($cache_key, $data, $group = 'default', $expire = 0, $ke return false; } - $fname = $group.':'.$cache_key; + $logkey = $this->item_hash($group).'-'.$this->item_hash($cache_key); + $logpref = __FUNCTION__.'():'; // skip save to disk, return true; if ('' === $data && $this->fs()->is_transient($group)) { if ($this->is_dev) { - $this->dc_log('debug', $fname, __FUNCTION__.'(): bypass-data-empty'); + $this->dc_log('debug', $logkey, $group.':'.$cache_key.' '.$logpref.' Data empty'); } return true; @@ -1451,7 +1353,7 @@ private function dc_save($cache_key, $data, $group = 'default', $expire = 0, $ke $data_serialized = serialize($data); $len = \strlen(serialize($data_serialized)); if ($len >= $this->cache_maxsize) { - $this->dc_log('err', $fname, 'Object too large: '.$len.'/'.$this->cache_maxsize); + $this->dc_log('err', $logkey, $group.':'.$cache_key.' '.$logpref.' Object too large -> '.$len.'/'.$this->cache_maxsize); return false; } @@ -1459,7 +1361,7 @@ private function dc_save($cache_key, $data, $group = 'default', $expire = 0, $ke // since timeout set to timestamp. if (0 === $expire && !empty($key) && @is_file($file) && $this->is_data_uptodate($key, $group, $data, $data_serialized)) { if ($this->is_dev) { - $this->dc_log('debug', $fname, __FUNCTION__.'()->nochanges'); + $this->dc_log('debug', $logkey, $group.':'.$cache_key.' '.$logpref.' No changes'); } return false; @@ -1505,7 +1407,7 @@ private function dc_save($cache_key, $data, $group = 'default', $expire = 0, $ke if (true === $this->dc_code($file, $meta)) { if ($this->is_dev) { - $this->dc_log('debug', $group.':'.$cache_key, __FUNCTION__.'()->todisk'); + $this->dc_log('debug', $logkey, $group.':'.$cache_key.' '.$logpref.' Storing to disk'); } return true; @@ -1540,10 +1442,12 @@ private function dc_update($cache_key, $data, $group) private function dc_precache_load($hash) { static $is_done = false; + $logkey = $this->item_hash('docketcache-precache').'-'.$this->item_hash(__FUNCTION__); + $logpref = __FUNCTION__.'():'; if ($is_done) { if ($this->is_dev) { - $this->dc_log('debug', 'internalproc-'.$this->item_hash(__FUNCTION__), 'Precache Ignored: Already loaded'); + $this->dc_log('debug', $logkey, $logpref.' Precache Ignored: Already loaded'); } return; @@ -1558,7 +1462,7 @@ private function dc_precache_load($hash) } if ($this->is_dev) { - $this->dc_log('debug', 'internalproc-'.$this->item_hash(__FUNCTION__), 'Precache Load: Start'); + $this->dc_log('debug', $logkey, $logpref.' Precache Load: Start'); } $this->precache_loaded[$hash] = $keys; @@ -1592,7 +1496,7 @@ private function dc_precache_load($hash) } if ($this->is_dev) { - $this->dc_log('debug', 'internalproc-'.$this->item_hash(__FUNCTION__), 'Precache Load: End -> '.\count($cached)); + $this->dc_log('debug', $logkey, $logpref.' Precache Load: End -> '.\count($cached)); } unset($keys, $cached); @@ -1613,8 +1517,11 @@ private function dc_precache_set($hash) $slowdown = 0; $cnt_max = 0; + $logkey = $this->item_hash('docketcache-precache').'-'.$this->item_hash(__FUNCTION__); + $logpref = __FUNCTION__.'():'; + if ($this->is_dev) { - $this->dc_log('debug', 'internalproc-'.$this->item_hash(__FUNCTION__), 'Precache Set: Start'); + $this->dc_log('debug', $logkey, $logpref.' Precache Set: Start'); } foreach ($this->precache as $cache_group => $cache_keys) { @@ -1631,7 +1538,7 @@ private function dc_precache_set($hash) if ($slowdown > 10) { $slowdown = 0; - usleep(5000); + usleep(100); } ++$slowdown; @@ -1645,20 +1552,13 @@ private function dc_precache_set($hash) } if ($this->is_dev) { - $this->dc_log('debug', 'internalproc-'.$this->item_hash(__FUNCTION__), 'Precache Set: End -> '.\count($data)); + $this->dc_log('debug', $logkey, $logpref.' Precache Set: End -> '.\count($data)); } if (!empty($data)) { - /*if ($this->is_data_uptodate($hash, $group, $data)) { - if ($this->is_dev) { - $this->dc_log('debug', $group.':'.$hash, __FUNCTION__.'()->nochanges'); - } - return; - }*/ - if (!empty($this->precache_loaded) && md5(serialize($this->precache_loaded[$hash])) === md5(serialize($data))) { if ($this->is_dev) { - $this->dc_log('debug', $group.':'.$hash, __FUNCTION__.'()->nochanges'); + $this->dc_log('debug', $logkey, $logpref.' '.$hash.' No changes'); } return; @@ -1679,18 +1579,29 @@ private function dc_precache() return; } - $logprefix = 'internalproc-'.$this->item_hash(__FUNCTION__); + $logkey = $this->item_hash('docketcache-precache').'-'.$this->item_hash(__FUNCTION__); + $logpref = __FUNCTION__.'():'; + $req_uri = $_SERVER['REQUEST_URI']; $dostrip = !empty($_SERVER['QUERY_STRING']); - if ($dostrip && !empty($_GET) && (isset($_GET['docketcache_ping']) || isset($_GET['doing_wp_cron']) || isset($_GET['_fs_blog_admin']) || isset($_GET['wc-ajax']) || !empty($_GET['_wpnonce']) || (!empty($_GET['action']) && false === strpos($req_uri, '/wp-admin/post.php?post=')) || !empty($_GET['message']))) { - $this->dc_log('info', $logprefix, 'docketcache-precache: bypass-rules-1'); + $intersect_key = [ + 'docketcache_ping' => 1, + 'doing_wp_cron' => 1, + 'wc-ajax' => 1, + '_fs_blog_admin' => 1, + 'action' => 1, + 'message' => 1, + ]; + + if ($dostrip && !empty($_GET) && array_intersect_key($intersect_key, $_GET)) { + $this->dc_log('info', $logkey, $logpref.' Bypass GET key'); return; } if (false !== strpos($req_uri, '/wp-json/') || false !== strpos($req_uri, '/wp-admin/admin-ajax.php') || false !== strpos($req_uri, '/xmlrpc.php') || false !== strpos($req_uri, '/wp-cron.php') || false !== strpos($req_uri, '/robots.txt') || false !== strpos($req_uri, '/favicon.ico')) { - $this->dc_log('info', $logprefix, 'docketcache-precache: bypass-rules-2'); + $this->dc_log('info', $logkey, $logpref.' Bypass Request'); return; } @@ -1730,20 +1641,20 @@ private function dc_precache() */ public function dc_close() { + $this->fs()->close_buffer(); static $is_done = false; - // only run one time if we can go into background - if ($this->fs()->close_buffer() && !$is_done) { - if ($this->is_precache && !empty($this->precache_hashkey)) { + if (!$is_done) { + if ($this->is_precache && !empty($this->precache_hashkey) && $this->fs()->close_buffer()) { $this->dc_precache_set($this->precache_hashkey); } - if ($this->cf()->is_dctrue('FLUSH_STALECACHE') && !empty($this->stalecache_list)) { - $this->flush_stalecache(); + if ($this->is_stalecache && !empty($this->stalecache_list)) { + $this->add('items', $this->stalecache_list, 'docketcache-stalecache', 3600); } - } - $is_done = true; + $is_done = true; + } } /** @@ -2000,11 +1911,23 @@ function () { ); } + // stalecache + $this->is_stalecache = $this->cf()->is_dctrue('FLUSH_STALECACHE'); + + // load precache $this->is_precache = $this->cf()->is_dctrue('PRECACHE'); if ($this->is_precache) { $this->precache_maxlist = (int) $this->cf()->dcvalue('PRECACHE_MAXLIST'); $this->dc_precache(); } + + // maxfile + $maxfile = (int) $this->fs()->sanitize_maxfile($this->cf()->dcvalue('MAXFILE')); + $numfile = (int) $this->get('numfile', 'docketcache-gc'); + $numfile = $numfile > 0 ? $numfile : 0; + if ($numfile > $maxfile) { + wp_suspend_cache_addition(true); + } } } diff --git a/includes/object-cache.php b/includes/object-cache.php index eeed973..2d0d4b7 100644 --- a/includes/object-cache.php +++ b/includes/object-cache.php @@ -3,7 +3,7 @@ * @wordpress-plugin * Plugin Name: Docket Cache Drop-in * Plugin URI: https://wordpress.org/plugins/docket-cache/ - * Version: 21.08.10 + * Version: 21.08.11 * Description: A persistent object cache stored as a plain PHP code, accelerates caching with OPcache backend. * Author: Nawawi Jamili * Author URI: https://docketcache.com diff --git a/includes/src/Command.php b/includes/src/Command.php index 0b94b1c..bff084e 100644 --- a/includes/src/Command.php +++ b/includes/src/Command.php @@ -496,10 +496,18 @@ public function run_gc() WP_CLI::line($this->title(__('Cleanup Cache File Limit', 'docket-cache'), $pad).$collect->cleanup_maxfile); WP_CLI::line($this->title(__('Cleanup Cache Disk Limit', 'docket-cache'), $pad).$collect->cleanup_maxdisk); - if ($this->pt->get_precache_maxfile() > 0) { + if ($collect->cleanup_expire > 0) { + WP_CLI::line($this->title(__('Cleanup Cache Expire', 'docket-cache'), $pad).$collect->cleanup_expire); + } + + if ($this->pt->get_precache_maxfile() > 0 && $collect->cleanup_precache_maxfile > 0) { WP_CLI::line($this->title(__('Cleanup Precache Limit', 'docket-cache'), $pad).$collect->cleanup_precache_maxfile); } + if ($this->pt->cf()->is_dctrue('FLUSH_STALECACHE') && $collect->cleanup_stalecache > 0) { + WP_CLI::line($this->title(__('Cleanup Stale Cache', 'docket-cache'), $pad).$collect->cleanup_stalecache); + } + WP_CLI::line(str_repeat('-', $pad).':'.str_repeat('-', 10)); WP_CLI::line($this->title(__('Total Cache Cleanup', 'docket-cache'), $pad).$collect->cache_cleanup); WP_CLI::line($this->title(__('Total Cache Ignored', 'docket-cache'), $pad).$collect->cache_ignore); diff --git a/includes/src/Constans.php b/includes/src/Constans.php index c80562d..2dc2d56 100644 --- a/includes/src/Constans.php +++ b/includes/src/Constans.php @@ -274,7 +274,7 @@ public function register_default() $this->maybe_define($this->px('PRECACHE'), false); // precache maxfile: < 1, false, null = unlimited - $this->maybe_define($this->px('PRECACHE_MAXFILE'), 0); + $this->maybe_define($this->px('PRECACHE_MAXFILE'), 1000); // precache maxlist $this->maybe_define($this->px('PRECACHE_MAXLIST'), 1000); diff --git a/includes/src/Crawler.php b/includes/src/Crawler.php index dee5b0e..13c6f48 100644 --- a/includes/src/Crawler.php +++ b/includes/src/Crawler.php @@ -14,7 +14,7 @@ final class Crawler { - private static $version = '21.08.10'; + private static $version = '21.08.11'; public static $send_cookie = false; private static function default_args($param = []) diff --git a/includes/src/Event.php b/includes/src/Event.php index 3e2e6ff..74a26ef 100644 --- a/includes/src/Event.php +++ b/includes/src/Event.php @@ -16,11 +16,15 @@ final class Event { private $pt; private $is_optimizedb; + private $max_execution_time = 0; + private $wp_start_timestamp = 0; public function __construct(Plugin $pt) { $this->pt = $pt; $this->is_optimizedb = false; + $this->wp_start_timestamp = \defined('WP_START_TIMESTAMP') ? WP_START_TIMESTAMP : microtime(true); + $this->max_execution_time = $this->pt->get_max_execution_time(); } /** @@ -190,6 +194,8 @@ public function watchproc() */ public function garbage_collector($force = false) { + static $is_done = false; + $maxfileo = (int) $this->pt->get_cache_maxfile(); $maxfile = $maxfileo; @@ -228,33 +234,41 @@ public function garbage_collector($force = false) 'cleanup_maxfile' => 0, 'cleanup_precache_maxfile' => 0, 'cleanup_maxttl' => 0, + 'cleanup_expire' => 0, 'cleanup_maxdisk' => 0, 'cache_file' => 0, 'cache_cleanup' => 0, 'cache_ignore' => 0, 'cleanup_failed' => 0, + 'cleanup_stalecache' => 0, ]; - $max_execution_time = $this->pt->get_max_execution_time(); - if ($this->pt->co()->lockproc('garbage_collector', time() + $max_execution_time + 10)) { + clearstatcache(); + if (!$this->pt->is_docketcachedir($this->pt->cache_path) || @is_file(DOCKET_CACHE_CONTENT_PATH.'/.object-cache-flush.txt')) { return $collect; } - clearstatcache(); - if (!$this->pt->is_docketcachedir($this->pt->cache_path) || @is_file(DOCKET_CACHE_CONTENT_PATH.'/.object-cache-flush.txt')) { + if ($is_done || $this->pt->co()->lockproc('garbage_collector', time() + $this->max_execution_time + 10)) { return $collect; } + $stalecache_list = []; + if ($this->pt->cf()->is_dctrue('FLUSH_STALECACHE')) { + $stalecache_list = wp_cache_get('items', 'docketcache-stalecache'); + wp_cache_delete('items', 'docketcache-stalecache'); + } + $delay = $force ? 650 : 5000; wp_suspend_cache_addition(true); $fsizetotal = 0; - $cnt = 0; + $fcnt = 0; $pcnt = 0; $slowdown = 0; + $slowdown2 = 0; foreach ($this->pt->scanfiles($this->pt->cache_path) as $object) { - if ($max_execution_time > 0 && \defined('WP_START_TIMESTAMP') && (microtime(true) - WP_START_TIMESTAMP) > $max_execution_time) { + if ($this->max_execution_time > 0 && (microtime(true) - $this->wp_start_timestamp) > $this->max_execution_time) { break; } @@ -283,6 +297,10 @@ public function garbage_collector($force = false) continue; } + if ($this->pt->cf()->is_dctrue('DEV') && 'cli' === \PHP_SAPI) { + echo 'run-gc: '.$fx."\n"; + } + if ($fm >= $ft && (0 === $fs || 'dump_' === substr($fn, 0, 5))) { $this->pt->unlink($fx, true); @@ -308,7 +326,10 @@ public function garbage_collector($force = false) } } - if ($cnt >= $maxfile) { + if ($fcnt >= $maxfile) { + // trigger WP_Object_Cache + wp_cache_set('numfile', $fcnt, 'docketcache-gc', 60); + $this->pt->unlink($fx, true); if ($force && @is_file($fx)) { @@ -334,8 +355,9 @@ public function garbage_collector($force = false) $data = $this->pt->cache_get($fx); $is_timeout = false; if (false !== $data) { + unset($data['data']); + $is_timeout = !empty($data['timeout']) && $this->pt->valid_timestamp($data['timeout']) ? true : false; - $docon = false; if ($is_timeout) { if ($fm >= (int) $data['timeout']) { $this->pt->unlink($fx, true); @@ -345,8 +367,8 @@ public function garbage_collector($force = false) } unset($data); - $docon = true; - ++$collect->cleanup_maxttl; + ++$collect->cleanup_expire; + continue; } } else { if (!empty($data['timestamp']) && $this->pt->valid_timestamp($data['timestamp']) && $maxttl > $data['timestamp']) { @@ -357,16 +379,11 @@ public function garbage_collector($force = false) } unset($data); - $docon = true; ++$collect->cleanup_maxttl; + continue; } } - - if ($docon) { - continue; - } } - unset($data); // no timeout data or 0 if (false === $is_timeout && $maxttl > 0 && $maxttl > $ft) { @@ -380,20 +397,119 @@ public function garbage_collector($force = false) continue; } - ++$cnt; + // stalecache + if ((!empty($stalecache_list) && \is_array($stalecache_list)) && !empty($data) && !empty($data['key']) && !empty($data['group']) && 'docketcache-stalecache' !== $data['group']) { + $collect->cleanup_stalecache += $this->flush_stalecache($fx, $data, $stalecache_list); + if ($collect->cleanup_stalecache > 0) { + continue; + } + } + unset($data); + + ++$fcnt; ++$collect->cache_file; - } + } // foreach1 - $collect->cache_cleanup = $collect->cleanup_maxttl + $collect->cleanup_maxfile + $collect->cleanup_maxdisk + $collect->cleanup_precache_maxfile; + $collect->cache_cleanup = $collect->cleanup_maxttl + $collect->cleanup_expire + $collect->cleanup_maxfile + $collect->cleanup_maxdisk + $collect->cleanup_precache_maxfile + $collect->cleanup_stalecache; wp_suspend_cache_addition(false); $this->pt->co()->lockreset('garbage_collector'); $this->pt->cx()->delay_expire(); + $is_done = true; + + // reset + wp_cache_delete('numfile', 'docketcache-gc'); + return $collect; } + /** + * flush_stalecache. + */ + public function flush_stalecache($file, $data, $stalecache_list) + { + $total = 0; + + if (!is_file($file) || empty($data) || empty($data['key']) || empty($data['group']) || empty($stalecache_list) || !\is_array($stalecache_list)) { + return $total; + } + + $slowdown = 0; + foreach ($stalecache_list as $id => $key) { + $do_flush = false; + + if (false !== strpos($data['key'], 'wc_cache_') && 'wc_cache:' === substr($key, 0, 9) && preg_match('@^wc_cache_([0-9\. ]+)_.*@', $data['key'], $mm)) { + list($prefix, $group, $usec) = explode(':', $key); + if ($usec === $mm[1]) { + $do_flush = true; + } else { + $usec1 = nwdcx_microtimetofloat($usec); + $usec2 = nwdcx_microtimetofloat($mm[1]); + if ($usec1 > $usec2) { + $do_flush = true; + } + } + + // group = from cache file, key = list key + } elseif (false !== strpos($data['group'], 'docketcache-post-') && false !== strpos($key, 'docketcache-post-')) { + if ($key === $data['group']) { + $do_flush = true; + } else { + $usec1 = str_replace('docketcache-post-', '', $key); + $usec2 = str_replace('docketcache-post-', '', $data['group']); + if ($usec1 > $usec2) { + $do_flush = true; + } + } + } elseif (false !== strpos($key, 'last_changed:') && @preg_match('@(.*):([a-z0-9]{32}):([0-9\. ]+)$@', $data['key'], $mm)) { + list($prefix, $group, $usec) = explode(':', $key); + if ($group === $data['group']) { + $usec1 = nwdcx_microtimetofloat($usec); + $usec2 = nwdcx_microtimetofloat($mm[3]); + if ($usec1 > $usec2) { + $do_flush = true; + } + } + } elseif (false !== strpos($key, 'after:') && @preg_match('@(.*):([a-z0-9]{32}):([0-9\. ]+)$@', $data['key'], $mm)) { + list($prefix, $group, $usec, $abc) = explode(':', $key); + if ($group === $data['group'] && $abc === $mm[1]) { + $usec1 = nwdcx_microtimetofloat($usec); + $usec2 = nwdcx_microtimetofloat($mm[3]); + if ($usec1 > $usec2) { + $do_flush = true; + } + } + } + + if ($do_flush) { + $nwdcx_suppresserrors = nwdcx_suppresserrors(true); + // use native unlink since it is a junk file. + if (@unlink($file)) { + unset($stalecache_list[$id]); + + if ($this->pt->cf()->is_dctrue('DEV') && 'cli' === \PHP_SAPI) { + echo 'run-gc:stale-cache: '.$file."\n"; + } + + ++$total; + } + nwdcx_suppresserrors($nwdcx_suppresserrors); + break; // found and break foreach + } + + if ($slowdown > 10) { + $slowdown = 0; + usleep(5000); + } + + ++$slowdown; + } + + return $total; + } + /** * optimizedb. */ @@ -416,7 +532,7 @@ public function optimizedb() $dbname = $wpdb->dbname; $tables = $wpdb->get_results('SHOW TABLES FROM '.$dbname, ARRAY_A); if (!empty($tables) && \is_array($tables)) { - $max_execution_time = $this->pt->get_max_execution_time(); + $max_execution_time = $this->max_execution_time; if ($max_execution_time < 300) { $max_execution_time = 300; } @@ -424,7 +540,7 @@ public function optimizedb() $tbl = $table['Tables_in_'.$dbname]; $wpdb->query('OPTIMIZE TABLE `'.$tbl.'`'); - if ($max_execution_time > 0 && \defined('WP_START_TIMESTAMP') && (microtime(true) - WP_START_TIMESTAMP) > $max_execution_time) { + if ($this->max_execution_time > 0 && (microtime(true) - $this->wp_start_timestamp) > $this->max_execution_time) { break; } } @@ -464,6 +580,9 @@ public function delete_expired_transients_db() */ public function clear_unknown_cron() { + // let's wp handles it. + return; + if (!wp_using_ext_object_cache()) { return; } @@ -476,7 +595,7 @@ public function clear_unknown_cron() foreach ($crons as $time => $cron) { foreach ($cron as $hook => $dings) { if (!has_action($hook)) { - //wp_clear_scheduled_hook($hook); + wp_clear_scheduled_hook($hook); } } } diff --git a/includes/src/Filesystem.php b/includes/src/Filesystem.php index ab925e8..fed1339 100644 --- a/includes/src/Filesystem.php +++ b/includes/src/Filesystem.php @@ -58,8 +58,8 @@ public function fastcgi_close() */ public function close_buffer() { - if (!@ob_get_level()) { - return $this->fastcgi_close(); + if (!@ob_get_level() && $this->fastcgi_close()) { + return true; } return false; @@ -392,7 +392,7 @@ public function export_var($data, &$error = '') $data = var_export($data, 1); $data = str_replace('stdClass::__set_state', '(object)', $data); } else { - $this->log('err', 'internalproc-internalfunc', 'export_var: '.$error); + $this->log('err', '000000000000-000000000000', 'export_var: '.$error); return false; } @@ -771,8 +771,10 @@ public function opcache_filecache_flush($file) */ public function opcache_filecache_reset() { + static $is_done = false; + $fcdata = $this->opcache_filecache_only(); - if (!empty($fcdata)) { + if (!$is_done && !empty($fcdata)) { $dir = $fcdata['file_cache']; $cnt = 0; $max_execution_time = $this->get_max_execution_time(); @@ -802,6 +804,8 @@ public function opcache_filecache_reset() } } + $is_done = true; + return $cnt; } @@ -915,7 +919,8 @@ public function opcache_cleanup() add_action( 'shutdown', function () { - $this->close_buffer(); + // anything involve disk, don't go into background + //$this->close_buffer(); $this->opcache_reset(); }, \PHP_INT_MAX @@ -956,6 +961,12 @@ public function define_cache_path($cache_path) */ public function cachedir_flush($dir, $cleanup = false, &$is_timeout = false) { + static $is_done = false; + + if ($is_done) { + return 0; + } + clearstatcache(); $dir = nwdcx_normalizepath(realpath($dir)); @@ -1014,6 +1025,7 @@ public function cachedir_flush($dir, $cleanup = false, &$is_timeout = false) } wp_suspend_cache_addition(false); + $is_done = true; return $cnt; } @@ -1023,12 +1035,14 @@ public function cachedir_flush($dir, $cleanup = false, &$is_timeout = false) */ public function cache_size($dir) { + static $is_done = false; + $bytestotal = 0; $fsizetotal = 0; $filestotal = 0; clearstatcache(); - if ($this->is_docketcachedir($dir) && !@is_file(DOCKET_CACHE_CONTENT_PATH.'/.object-cache-flush.txt')) { + if (!$is_done && $this->is_docketcachedir($dir) && !@is_file(DOCKET_CACHE_CONTENT_PATH.'/.object-cache-flush.txt')) { // hardmax $maxfile = 999000; // 1000000 - 1000; $cnt = 0; @@ -1040,7 +1054,7 @@ public function cache_size($dir) $pattern = '@^([a-z0-9]{12})\-([a-z0-9]{12})\.php$@'; foreach ($this->scanfiles($dir, null, $pattern) as $object) { try { - if ($object->isFile() && 'dump_' !== substr($object->getFileName(), 0, 5)) { + if ($object->isFile()) { $fx = $object->getPathName(); if (!$this->remove_non_chunk_cache($dir, $fx)) { @@ -1083,6 +1097,10 @@ public function cache_size($dir) } } + $is_done = true; + + wp_cache_set('numfile', $filestotal, 'docketcache-gc', 60); + return [ 'timestamp' => time(), 'size' => $bytestotal, @@ -1215,7 +1233,7 @@ public function cache_get($file) $this->suspend_cache_file($file, $errmsg); } - $this->log('err', 'internalproc-internalfunc', 'cache_get: '.$error); + $this->log('err', '000000000000-000000000000', 'cache_get: '.$error); $data = false; } diff --git a/includes/src/PostCache.php b/includes/src/PostCache.php index 0922152..0e8a468 100644 --- a/includes/src/PostCache.php +++ b/includes/src/PostCache.php @@ -27,6 +27,7 @@ final class PostCache public $cache_func_expiry = 0; // let WP_Object_Cache::maybe_expire handles it public $stalecache_list = []; public $allow_posttype = ['post', 'page', 'attachment']; + public $blacklist_posttype = ['scheduled-action']; public $allow_posttype_all = false; public function __construct() @@ -239,7 +240,7 @@ public function invalidate_cache() private function allow_post_type($post_type) { - if ($this->allow_posttype_all) { + if ($this->allow_posttype_all && !\in_array($post_type, $this->blacklist_posttype)) { return true; } @@ -397,7 +398,9 @@ public function found_posts($found_posts, $query) public function stalecache_set() { if (!empty($this->stalecache_list) && \function_exists('wp_cache_add_stalecache')) { - wp_cache_add_stalecache($this->stalecache_list); + $key_last = array_key_last($this->stalecache_list); + $list = [$key_last => $this->stalecache_list[$key_last]]; + wp_cache_add_stalecache($list); } } } diff --git a/includes/src/ReqAction.php b/includes/src/ReqAction.php index edf973a..07cbabe 100644 --- a/includes/src/ReqAction.php +++ b/includes/src/ReqAction.php @@ -753,10 +753,18 @@ private function screen_notice() $gcmsg .= '
  • '.esc_html__('Cleanup Cache File Limit', 'docket-cache').''.$collect->cleanup_maxfile.'
  • '; $gcmsg .= '
  • '.esc_html__('Cleanup Cache Disk Limit', 'docket-cache').''.$collect->cleanup_maxdisk.'
  • '; - if ($this->pt->get_precache_maxfile() > 0) { + if ($collect->cleanup_expire > 0) { + $gcmsg .= '
  • '.esc_html__('Cleanup Cache Expire', 'docket-cache').''.$collect->cleanup_expire.'
  • '; + } + + if ($this->pt->get_precache_maxfile() > 0 && $collect->cleanup_precache_maxfile > 0) { $gcmsg .= '
  • '.esc_html__('Cleanup Precache Limit', 'docket-cache').''.$collect->cleanup_precache_maxfile.'
  • '; } + if ($this->pt->cf()->is_dctrue('FLUSH_STALECACHE') && $collect->cleanup_stalecache > 0) { + $gcmsg .= '
  • '.esc_html__('Cleanup Stale Cache', 'docket-cache').''.$collect->cleanup_stalecache.'
  • '; + } + $gcmsg .= '
  • '.esc_html__('Total Cache Cleanup', 'docket-cache').''.$collect->cache_cleanup.'
  • '; $gcmsg .= '
  • '.esc_html__('Total Cache Ignored', 'docket-cache').''.$collect->cache_ignore.'
  • '; $gcmsg .= '
  • '.esc_html__('Total Cache File', 'docket-cache').''.$collect->cache_file.'
  • '; diff --git a/includes/src/View.php b/includes/src/View.php index 929af02..efab105 100644 --- a/includes/src/View.php +++ b/includes/src/View.php @@ -614,8 +614,8 @@ private function tooltip($id) 'opcshutdown' => esc_html__('Flush OPcache when deactivate / uninstall.', 'docket-cache'), 'maxsize_disk' => esc_html__('Maximum size of the cache storage on disk. The garbage collector will remove the cache file to free up storage space.', 'docket-cache'), 'maxfile' => esc_html__('The maximum cache file can be stored on a disk. The cache file will free up by the garbage collector when triggered by WP Cron.', 'docket-cache'), - 'chunkcachedir' => esc_html__('Enable this option to chunk cache files into a smaller directory to avoid an excessive number of cache files in a single directory.', 'docket-cache'), - 'flush_stalecache' => esc_html__('Enable this option to immediately remove the stale cache abandoned by WordPress, WooCommerce and others after doing cache invalidation.', 'docket-cache'), + 'chunkcachedir' => esc_html__('Enable this option to chunk cache files into a smaller directory to avoid an excessive number of cache files in a single directory. Only enable this option if you have difficulty when manually clearing the cache or experience a slowdown when the cache becomes too large.', 'docket-cache'), + 'flush_stalecache' => esc_html__('Enable this option to immediately remove the stale cache abandoned by WordPress, WooCommerce and others after doing cache invalidation. By default, it will be removed by GC within 4 days. This option may cause exessive usage of I/O and CPU. Only enable this option if you require to keep storage space in check.', 'docket-cache'), 'limithttprequest' => esc_html__('Limit HTTP requests in WP Admin.', 'docket-cache'), 'httpheadersexpect' => esc_html__('By default, cURL sends the "Expect" header all the time which severely impacts performance. Enable this option, only send it if the body is larger than 1 MB.', 'docket-cache'), 'rtpostautosave' => esc_html__('WordPress by default automatically saves a draft every 1 minute when editing or create a new post. Changing this behaviour can reduce the usage of server resource.', 'docket-cache'), diff --git a/languages/docket-cache.pot b/languages/docket-cache.pot index 03689e5..277dcd1 100644 --- a/languages/docket-cache.pot +++ b/languages/docket-cache.pot @@ -2,14 +2,14 @@ # This file is distributed under the MIT. msgid "" msgstr "" -"Project-Id-Version: Docket Cache 21.08.10\n" +"Project-Id-Version: Docket Cache 21.08.11\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/docket-cache\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2022-05-19T18:31:55+00:00\n" +"POT-Creation-Date: 2022-05-30T13:40:11+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.5.0\n" "X-Domain: docket-cache\n" @@ -189,8 +189,8 @@ msgstr "" #: includes/admin/config.php:416 #: includes/admin/config.php:433 #: includes/admin/config.php:453 -#: includes/admin/config.php:504 -#: includes/admin/config.php:533 +#: includes/admin/config.php:492 +#: includes/admin/config.php:521 #: includes/admin/log.php:31 #: includes/src/View.php:427 msgid "Default" @@ -347,7 +347,7 @@ msgid "Every Minute" msgstr "" #: includes/admin/config.php:300 -#: includes/src/Event.php:58 +#: includes/src/Event.php:62 msgid "Every 5 Minutes" msgstr "" @@ -388,7 +388,7 @@ msgstr "" #: includes/admin/config.php:326 #: includes/src/Canopt.php:134 -#: includes/src/ReqAction.php:793 +#: includes/src/ReqAction.php:801 msgid "Trash Bin" msgstr "" @@ -455,23 +455,12 @@ msgid "Storage Options" msgstr "" #: includes/admin/config.php:474 -#: includes/admin/overview.php:177 -#: includes/src/Canopt.php:128 -msgid "Chunk Cache Directory" -msgstr "" - -#: includes/admin/config.php:480 -#: includes/src/Canopt.php:129 -msgid "Auto Remove Stale Cache" -msgstr "" - -#: includes/admin/config.php:486 #: includes/admin/overview.php:162 #: includes/src/Canopt.php:127 msgid "Cache Files Limit" msgstr "" -#: includes/admin/config.php:515 +#: includes/admin/config.php:503 #: includes/admin/overview.php:167 #: includes/src/Canopt.php:126 #: includes/src/Command.php:493 @@ -479,6 +468,17 @@ msgstr "" msgid "Cache Disk Limit" msgstr "" +#: includes/admin/config.php:532 +#: includes/admin/overview.php:177 +#: includes/src/Canopt.php:128 +msgid "Chunk Cache Directory" +msgstr "" + +#: includes/admin/config.php:538 +#: includes/src/Canopt.php:129 +msgid "Auto Remove Stale Cache" +msgstr "" + #: includes/admin/config.php:545 msgid "Admin Interface" msgstr "" @@ -1220,7 +1220,7 @@ msgid "Updating wp-config.php file successful" msgstr "" #: includes/src/Command.php:297 -#: includes/src/ReqAction.php:776 +#: includes/src/ReqAction.php:784 msgid "Failed to update wp-config.php file." msgstr "" @@ -1251,7 +1251,7 @@ msgid "The transient was flushed. Total cache flushed: %d" msgstr "" #: includes/src/Command.php:365 -#: includes/src/ReqAction.php:883 +#: includes/src/ReqAction.php:891 msgid "Advanced Post Cache could not be flushed." msgstr "" @@ -1349,25 +1349,35 @@ msgstr "" #: includes/src/Command.php:500 #: includes/src/ReqAction.php:757 -msgid "Cleanup Precache Limit" +msgid "Cleanup Cache Expire" msgstr "" #: includes/src/Command.php:504 -#: includes/src/ReqAction.php:760 +#: includes/src/ReqAction.php:761 +msgid "Cleanup Precache Limit" +msgstr "" + +#: includes/src/Command.php:508 +#: includes/src/ReqAction.php:765 +msgid "Cleanup Stale Cache" +msgstr "" + +#: includes/src/Command.php:512 +#: includes/src/ReqAction.php:768 msgid "Total Cache Cleanup" msgstr "" -#: includes/src/Command.php:505 -#: includes/src/ReqAction.php:761 +#: includes/src/Command.php:513 +#: includes/src/ReqAction.php:769 msgid "Total Cache Ignored" msgstr "" -#: includes/src/Command.php:506 -#: includes/src/ReqAction.php:762 +#: includes/src/Command.php:514 +#: includes/src/ReqAction.php:770 msgid "Total Cache File" msgstr "" -#: includes/src/Command.php:508 +#: includes/src/Command.php:516 msgid "Executing the garbage collector completed." msgstr "" @@ -1392,19 +1402,19 @@ msgstr "" msgid "Already received. Try again in a few minutes" msgstr "" -#: includes/src/Event.php:39 +#: includes/src/Event.php:43 msgid "Every 30 Minutes" msgstr "" -#: includes/src/Event.php:45 +#: includes/src/Event.php:49 msgid "Once Hourly" msgstr "" -#: includes/src/Event.php:52 +#: includes/src/Event.php:56 msgid "Once Monthly" msgstr "" -#: includes/src/Event.php:63 +#: includes/src/Event.php:67 msgid "Every 15 Days" msgstr "" @@ -1655,11 +1665,11 @@ msgstr "" #: includes/src/ReqAction.php:558 #: includes/src/ReqAction.php:578 -#: includes/src/ReqAction.php:821 -#: includes/src/ReqAction.php:839 -#: includes/src/ReqAction.php:857 -#: includes/src/ReqAction.php:875 -#: includes/src/ReqAction.php:893 +#: includes/src/ReqAction.php:829 +#: includes/src/ReqAction.php:847 +#: includes/src/ReqAction.php:865 +#: includes/src/ReqAction.php:883 +#: includes/src/ReqAction.php:901 msgid "Total cache flushed" msgstr "" @@ -1818,80 +1828,80 @@ msgstr "" msgid "Executing the garbage collector successful" msgstr "" -#: includes/src/ReqAction.php:770 +#: includes/src/ReqAction.php:778 msgid "Failed to run the garbage collector." msgstr "" -#: includes/src/ReqAction.php:773 +#: includes/src/ReqAction.php:781 msgid "Updating wp-config.php file successful." msgstr "" -#: includes/src/ReqAction.php:779 +#: includes/src/ReqAction.php:787 msgid "Reset all configuration successful." msgstr "" -#: includes/src/ReqAction.php:782 +#: includes/src/ReqAction.php:790 msgid "Failed to reset configuration." msgstr "" -#: includes/src/ReqAction.php:785 +#: includes/src/ReqAction.php:793 msgid "Cleanup Post successful" msgstr "" -#: includes/src/ReqAction.php:791 +#: includes/src/ReqAction.php:799 msgid "Revisions" msgstr "" -#: includes/src/ReqAction.php:792 +#: includes/src/ReqAction.php:800 msgid "Auto Drafts" msgstr "" #. translators: %d = sites -#: includes/src/ReqAction.php:798 +#: includes/src/ReqAction.php:806 msgid "For %d sites" msgstr "" -#: includes/src/ReqAction.php:808 +#: includes/src/ReqAction.php:816 msgid "Failed to cleanup Post." msgstr "" -#: includes/src/ReqAction.php:811 +#: includes/src/ReqAction.php:819 msgid "Post already cleanup. Try again in a few seconds." msgstr "" -#: includes/src/ReqAction.php:814 +#: includes/src/ReqAction.php:822 msgid "Menu cache was flushed." msgstr "" -#: includes/src/ReqAction.php:829 +#: includes/src/ReqAction.php:837 msgid "Menu cache could not be flushed." msgstr "" -#: includes/src/ReqAction.php:832 +#: includes/src/ReqAction.php:840 msgid "Translation cache was flushed." msgstr "" -#: includes/src/ReqAction.php:847 +#: includes/src/ReqAction.php:855 msgid "Translation cache could not be flushed." msgstr "" -#: includes/src/ReqAction.php:850 +#: includes/src/ReqAction.php:858 msgid "Object Precache was flushed." msgstr "" -#: includes/src/ReqAction.php:865 +#: includes/src/ReqAction.php:873 msgid "Object Precache could not be flushed." msgstr "" -#: includes/src/ReqAction.php:868 +#: includes/src/ReqAction.php:876 msgid "Advanced Post Cache was flushed." msgstr "" -#: includes/src/ReqAction.php:886 +#: includes/src/ReqAction.php:894 msgid "Transient cache was flushed." msgstr "" -#: includes/src/ReqAction.php:901 +#: includes/src/ReqAction.php:909 msgid "Transient cache could not be flushed." msgstr "" @@ -2109,11 +2119,11 @@ msgid "The maximum cache file can be stored on a disk. The cache file will free msgstr "" #: includes/src/View.php:617 -msgid "Enable this option to chunk cache files into a smaller directory to avoid an excessive number of cache files in a single directory." +msgid "Enable this option to chunk cache files into a smaller directory to avoid an excessive number of cache files in a single directory. Only enable this option if you have difficulty when manually clearing the cache or experience a slowdown when the cache becomes too large." msgstr "" #: includes/src/View.php:618 -msgid "Enable this option to immediately remove the stale cache abandoned by WordPress, WooCommerce and others after doing cache invalidation." +msgid "Enable this option to immediately remove the stale cache abandoned by WordPress, WooCommerce and others after doing cache invalidation. By default, it will be removed by GC within 4 days. This option may cause exessive usage of I/O and CPU. Only enable this option if you require to keep storage space in check." msgstr "" #: includes/src/View.php:619 diff --git a/readme.txt b/readme.txt index 73cb687..4377c9c 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: object cache, OPcache, fastcgi, cache, database, Optimisation, performance Requires at least: 5.4 Tested up to: 6.0 Requires PHP: 7.2.5 -Stable tag: 21.08.10 +Stable tag: 21.08.11 License: MIT License URI: https://github.com/nawawi/docket-cache/blob/master/LICENSE.txt @@ -171,6 +171,12 @@ Yes, you can. It can boost more your WordPress performance since there is no net Please do manually remove wp-content/object-cache.php and wp-content/cache/docket-cache if an error occurs during updates. Thanks. == Changelog == += 21.08.11 = +- Fixed: Avoid calling Filesystem::close_buffer() if a process involved accessing a disk. +- Fixed: Removed handling stale cache on shutdown. +- Added: Garbage Collector Status -> Cleanup Stale Cache. +- Improved: Collected stale cache will be handled by Garbage Collector. + = 21.08.10 = - Changed: Disable "Chunk Cache Directory" by default. Let's users choose it depending on their hosting environment.