Problem/Motivation
The asset_injector directory in the public files in emptied on every cache rebuild in hook_cache_flush().
/**
* Implements hook_cache_flush().
*
* Delete all asset files.
*/
function asset_injector_cache_flush() {
AssetFileStorage::deleteAllFiles();
}
This adds an unnecessary load on the server, since there were no changes to any asset injector configuration.
This leads to a state where (when the cache is rebuilt with drush) the files can take on the user ownership of the user who rebuilt the cache. This will cause issues when a user attempts to rebuild the cache with the UI.
Proposed resolution
Do not empty the asset_injector directory on every cache rebuild. Instead use an EventListener for ConfigEvents::SAVE and then update the necessary files. This was suggested in #4 in the issue this hook was introduced, see #2869562-4: Deployment does not change asset files
Remaining tasks
- Write a patch
- Review
- Commit
User interface changes
None.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | 3077939-cache-rebuild-error-9.patch | 607 bytes | frob |
Comments
Comment #2
idebr commentedComment #3
pookmish commentedThis was a design choice to assist with any issues during code deployments or global changes. It is a desired result.
Currently when a config is saved it only deletes and rebuilds the files for that one entity. During Presave the files for that one config are deleted.
There shouldn't be full site cache clear that often and even so writing a few files shouldn't impact the server enough to be of a concern. If there are that many asset files, I'd strongly suggest moving them into a theme for better performance & maintenance.
An alternative you might go down is decorating the service to your liking and clearing out that method.
Comment #4
idebr commentedTo provide a bit more information: rebuilding the file structure during a cache rebuild was causing file permission problems during automatic deployments for our company projects. The automated deployment contains the following steps:
cache rebuild: ./asset_injector directory is removed
check status requirements: ./asset_injector directory is recreated, but as the deploying user (in our case jenkins)
As a result, the webserver running as www-data could no longer write to the directory. We changed the 'check status requirements' step to run as the webserver user (www-data), so the asset_injector directory was created with the correct owner.
Comment #5
frobWe have come across this issue with our deployments and during development. What is happening is when we use Drush to rebuild the cache the files are generated as our user. Afterward if someone edits an asset or clears the cache from Drupal's UI it results in a WSOD type error. This can be fixed with a try/catch block in the hook.
Something like this would stop the cache process from generating a WSOD.
Comment #6
frobComment #7
pookmish commentedI can see an try catch here, but it really just masks the true issue which is the user and file permissions.
The files being generated should have permission for the web server to delete them. That could be done by manipulating the user roles and apache/nginx roles on the server itself. Any file within the `public://` directory should have permissions for the webserver to modify them. You should investigate that.
Comment #8
frobThe problem comes from drush running as the user who ran it and drush cr is a common practice. This means that when drush cr is run then the web server may end up in a state where it cannot clear the cache from the UI.
The try/catch doesn't mask the issue it allows us to not hard fail when the issue comes up. As it stands now, it is really easy for a user of this module to end up in a situation where Drupal cannot be cleared through the UI. The issue is really around the cache clearing process being halted by the error caused by this not being in a try/catch block.
Comment #9
frobHere is a patch with the above change.
Comment #10
frobComment #11
frobComment #12
frobSorry for all the comment notifications.
Comment #13
pookmish commentedI don't see any harm in adding the additional message. Thanks.
Comment #15
pookmish commentedComment #17
dqdDoes this have been merged into the latest release? It feels like not. But if yes then it maybe creates a follow up. On backup and restore on local stage css/js rule sets are listed in config UI but the files not loaded on page load because the css/ and js/ directory gets completely removed from files/asset_injector/ directory after cache clear. Even cron run does not bring them back. And no, it is not a permission issue because removing and recreating them requires the same permissions and apart from that they are identical on both stages. Additionally I do not see a good reason for removing these directories on cache clear. That feels a little bit too obtrusive.
Comment #18
mlncn commentedBelieve we may also be seeing this.