We recently noticed a situation where a cached page on a reverse-proxy (in our case, cloudflare) was referring to a deleted aggregated js file, and so was getting a 404 response on that file, so the page was broken.
Drupal uses a configuration setting (system.performance.stale_file_threshold) to perform garbage collection of optimized js and css assets.
This is set by default to 30 days.
Our problem is that the js file was deleted from the file system, even though a reference for the js file still exists in the cloudflare cache.
This is a large-scale site, so we avoid purging the cloudflare cache if we can help it, so the situation may arise when the cloudflare page is referencing a deleted js file, simply because the js file was generated more than 30 days ago.
Looking at the following code (src/docroot/core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php:177)
public function deleteAll() {
$this->state->delete('system.js_cache_files');
$delete_stale = function ($uri) {
// Default stale file threshold is 30 days.
if (REQUEST_TIME - filemtime($uri) > \Drupal::config('system.performance')->get('stale_file_threshold')) {
file_unmanaged_delete($uri);
}
};
file_scan_directory('public://js', '/.*/', ['callback' => $delete_stale]);
}
... I am wondering if it might be better (depending on a config setting, and if the underlying file system supports it) to use fileatime() as the check instead of filemtime().
In other words, we would only mark the asset file as stale, if it hasn't been *accessed* in over 30 days, rather than depending on whether it was *modified* over 30 days ago.