-
Notifications
You must be signed in to change notification settings - Fork 84
[SymfonyCache] Prevent event class from being cached by Symfony's class cache #244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Argh, just realized that this does not work as expected @stof because the Maybe we have to load classes in the bundle's boot method. |
Even this does not work, because the class cache is created before the bundles are booted. My last idea is to load the class in the Any ideas? |
we could introduce a constructor argument, defaulting to assume the AppCache is used. or is there a reliable way to discover whether the AppCache is in place? ah - might even be different for web requests and cli :-( i am not sure how relevant the penalty it is, because in a setup where performance really matters, an opcache should be used anyways, which makes the class caches rather irrelevant. afaik the classes.php is only relevant for systems without opcache. @stof wdyt? |
Yes, that's true ;-) I've extended the constructor of class public function __construct(HttpKernelInterface $kernel, $cacheDir = null)
{
$this->preloadClasses();
// ....
}
// ....
protected function preloadClasses()
{
class_exists('FOS\\HttpCache\\SymfonyCache\\CacheEvent');
} As If there are no objections I'll commit this solution and hope that it will get pulled. |
i see two problems: will the AppCache even be instantiated when running on the command line? and for version 2, we are refactoring this base class into a trait: FriendsOfSymfony/FOSHttpCache#233 with the trait, this solution no longer works. i think we should do it in the bundle class that is instantiated by AppKernel, and have an optional constructor argument to disable the preloading if its not wanted. |
No, AppCache is not loaded in I have tried to load that class in the bundle constructor. But even there it does not work, because the bundles are loaded after the class cache has been loaded (see |
indeed :-( so what can we do? i can only see that we document for the user to
not very nice but i can't think of a different solution. other ideas? |
Why not in AppCache? Or we reconsider using my first approach with overwriting the class mapping as I have done in #243 . It is not that nice, but there is no nice solution as we realized :-( |
if AppCache is not executed on console, it is not the place to do this.
and with the trait it will not be easier than AppKernel - the user needs
to be aware of it and do something actively. i can't see how we could
work around that without having the user do something.
|
Why that? AppCache is not loaded in console, so EventDispatchingHttpCache isn't loaded neither, which means that there won't be any redeclaration errors in console ;-) |
but is the cache not also build when the console is run? and when later we have a web request, we get the error? |
@Naitsirch |
@dbu hm... usually that's not the case, because in console the Kernel is not told to load the class cache. But there may be people who turn that on. Then the error will occure. @stof But the
For better unterstanding:
What does that mean:
Solutions:
|
hm, but i think i still did not get it. that classes.map file is only built if loadClassCache was called. but it is only done at AppKernel::boot, so after AppCache::handle started. that handle method however triggers one of our events. so the classes should be properly seen, or not? or do we need a class_exists in case there are no event listeners? do we try to load the class before the cache is built, so that the cache building sees that this class is needed? |
No, the classes.map is build on cache warming. The classes.php is built on kernel boot if loadClassCache was called.
This is a bit complicated. The Then later when a POST request is done, the If the first request after a cache warmup is a POST request, the
The class is not loaded if it's a GET request. Sorry, if I am sometimes a bit unclear. |
I have tested adding |
okay, i think i am slowly getting it. no need to apologize, i don't think you are unclear. its just really quite complicated. would it always work if we do the the problem with the constructor is that we are moving towards a trait, where we won't tell people anymore what constructor they should have. |
As far as I see, it would work. But only if |
doing loadClassCache in app/console is not the default behaviour. so i would just add a warning in the documentation about the app/console topic. and if people don't read the doc but do optimizations, they hopefully find the doc when googling about the error... and given how magically that class cache is built, using loadClassCache in the console and app.php sounds like inviting some disaster anyways. i suggest that we add this trick to the |
…nt redeclaration error described in FriendsOfSymfony#242
@dbu I have updated the PR to reflect our latest idea and added some documentation how to handle the redeclaration error if I hope this is fine now :-) Maybe you could pick it and put it into the trait in master? |
Can somebody tell me what's wrong with my change in file |
sure, will port that to the trait. will have some time for this tomorrow.
the build failure is because the spell checker is not happy with some of
the words. app, dev and php are not in its dictionary, will need to look
whether we find a different way of saying it, or put it as `code` that
is not checked. "occure" should probably be "occurs"
|
Okay, the spelling errors are fixed, now. But there is still one problem. I don't know how this could be introduced by my PR:
|
see FriendsOfSymfony/FOSHttpCache#249 thanks a lot @Naitsirch for digging through this. i hope we manage to update the bundle to 2.0 soon, then the problem will go away here as well. |
This PR is basing on #243 and @stof 's idea for improvement.
Symfony's class cache (cache//classes.php) compiles classes that are loaded on each request.
But when using
EventDispatchingHttpCache
there may occure errors, when using Symfony's HttpCache, because EventDispatchingHttpCache loads some classes (Symfony\Component\EventDispatcher\Event
) individually via autoload and later when the HttpKernel is bootet in a subrequest and the class cache is loaded, PHP runs into a fatal error because of redeclaration of the classSymfony\Component\EventDispatcher\Event
(as you can see in #242).To fix this issue I have added an compiler pass which autoloads
Symfony\Component\EventDispatcher\Event
during cache building phase, so that Symfony removes it from its cache class map before the cache is built. This only happens if cache invalidation is used (as it only happens in that case, afaik).If there are any objections/annotations to this PR, please let me know.