Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[HttpKernel][HttpFoundation] Prototype: Service reset as middleware #24697

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

Closed
wants to merge 1 commit into from

Conversation

derrabus
Copy link
Member

Q A
Branch? 3.4
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #24552, #24554
License MIT
Doc PR N/A

This PR drafts an alternative approach to #24689.

Problem

The problem of #24552 is that #24155 introduced a behavior change of the kernel.terminate event because services were reset after a request has been processed. This caused issues with existing tests written with WebTestCase that tried to assert the state of certain services after a request.

Approach

The idea behind the approach of this PR is that the affected services could very well be reset at the very beginning of a new request. Because we reset the profiler that collects data from the event dispatcher, we need to perform the reset before the event dispatcher is used for the first time.

Since Symfony does not have a proper extension point for this kind of functionality, I propose to add the service reset as a middleware between Kernel and HttpKernel, making it transparent to both of them.

Alternatives

  • [HttpFoundation][HttpKernel] Move ServiceResetListener logic to RequestStack #24689 also resets services at the beginning of a new request, but does so by decorating RequestStack which so far only was a plain and simple data structure. That PR would introduce a somewhat unexpected side effect.
  • A simpler, low impact alternative would be to convert the current ServiceResetListener into a regular public service that is directly being called by Kernel::handle(). This would avoid the middleware, but would allow us to easily refactor the feature into a middleware if we decide to introduce that concept later.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Oct 26, 2017

Wondering a bit about this, I think we should just provide a (private) service that just calls the reset methods.
This service would only provide a single "reset()" method doing so.
Then, let's not wire it by default (it would be removed as unused in regular app), and let php-pm & similar use it when they actually require that resetting feature (through a middleware, or any other mean really).
@derrabus up to update this PR in this direction?

<argument key="$services" /> <!-- ResettableServicePass will inject an iterator of initialized services here ($serviceId => $serviceInstance) -->
<argument key="$resetMethods" type="collection" /> <!-- ResettableServicePass will inject an array of reset methods here ($serviceId => $method) -->
</service>
<service id="http_kernel" alias="Symfony\Component\HttpKernel\Middleware\ServiceResetMiddleware" public="true" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than doing this (which makes the HttpKernel typehint autowirable btw), I would rather keep the http_kernel as it is currently, and then use service decoration when the reset middleware is needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we do not implement a switch for turning off that feature (which was the whole point of moving the reset to the beginning), the middleware would technically be always present.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I agree that enabling HttpKernel for autowiring could cause accidents. ;-)

@derrabus
Copy link
Member Author

Introducing the concept of middlewares between betas is probably not a good idea.

@nicolas-grekas as I had a little chat and we agreed on providing the service resetter as a service, so PHP-PM and whoever else would want to fire multiple requests against HttpKernel could use it to prepare the kernel for the next request. In other words, the reset would not happen automatically anymore.

For Symfony 4.1, I will look into generalizing middlewares, as I think they could be a helpful extension point. And maybe we can reenable the automatism again, then.

@nicolas-grekas
Copy link
Member

See alternative in #24709

@nicolas-grekas nicolas-grekas added this to the 3.4 milestone Oct 27, 2017
@nicolas-grekas
Copy link
Member

Closing in favor of #24709

@derrabus derrabus deleted the 3.4-resetter-middleware branch October 30, 2017 15:46
fabpot added a commit that referenced this pull request Oct 30, 2017
…) (nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[HttpKernel] Move services reset to Kernel::handle()+boot()

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #24552
| License       | MIT
| Doc PR        | -

This is an alternative to #24697 (which uses middlewares).
This PR adds a new `services_resetter` service that the Kernel calls on 2nd root requests to reset services.
Instead of #24697 which plans for optional enabling of the services reset, this approach moves the responsibility of calling the services resetter to the core Kernel class, so that no configuration/middleware/etc. is required at all, and no overhead exists at all for regular requests.

Commits
-------

4501a36 [HttpKernel] Move services reset to Kernel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants