Closed
Description
Currently the caching of the Translator component is sprinkled all over the place:
- The Translator itself has a notion that catalogues can be cached (see Translator#loadCatalogue)
- The Translator Fileloader knows about the Config component for caching (see FileLoader#load)
- The Container has
FileResourcesFileExistenceResource
s andDirectoryResource
s for translation files so the Container itself will be deemed non fresh when the translation files have changed (see FrameworkExtension#registerTranslatorConfiguration) For some reason the Translator and the Router share the same ConfigCacheFactory (see here and here)as @stof pointed out this isn't true- All of the above is focused on caching files only, there is no notion of directories
This has the following drawbacks:
- The Translator has too many responsibilities and thus too many reasons to change
- There is double bookkeeping going on between the Container and Catalogues, so that when a translation file changes both the Container and the Translator cache need to be refreshed, whereas a refresh of just the Translator cache would suffice
- When a new translation file is added to a directory the container will conclude it needs a refresh (because it has DirectoryResources for the translation directories), but the catalogue itself will never consider the new file (because it only has FileResources, no DirectoryResources - see Add new translation files without clearing the cache #27600)
When the routing configuration changes the translator has to be rebuilt and vice versa (because of the shared ConfigCacheFactory)as @stof pointed out this isn't true
Proposal to solve these drawbacks:
- Remove the responsibility of loading catalogues from the Translator, give this responsibility to a new MessageCatalogueLoader that knows how to load catalogues, but has no idea about caching
- Add a CachedMessageCatalogueLoader that can decorate the MessageCatalogueLoader (so they both implement a common interface) and that knows how to cache catalogues, but has no idea how to load them (it delegates this to the MessageCatalogueLoader). This CachedMessageCatalogueLoader would also implement
SelfCheckingResourceInterface
, so it can indicate to the Container when it's no longer fresh - the container no longer needs to concern itself with that. This also decouples the Translator cache from the Router cache. Remove the notion of caching from the FileLoader class- as @stof pointed out this isn't going to work because the decorator would need too much knowledge about what it's decoratingAdd a CacheAwareFileloader that decorates all FileLoaders to add caching (add FileResource to catalogue on load). Symfony Framework would use this decoration by default, but for the Translator component it's optional.- as @stof pointed out this isn't going to work because the decorator would need too much knowledge about what it's decorating- Add a new DirectoryLoader that iterates all files in a directory and passes all files to FileLoaders to be loaded
Add a CacheAwareDirectoryLoader that decorates DirectoryLoader to add the notion of caching (add DirectoryResource to catalogue on load). Symfony Framework would use this decoration by default, but for the Translator component it's optional.- as @stof pointed out this isn't going to work because the decorator would need too much knowledge about what it's decorating
There are still a lot of implementation details to be considered, but this is the broad overview.
I'd love to hear what people think about this proposal!
If anything is unclear I'd love to clarify - ask me anything!
Also, I'd be willing to create a PR for this if this RFC gets accepted