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

Skip to content

Implement resettable containers #15185

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

Merged
merged 1 commit into from
Jul 23, 2015
Merged

Conversation

stof
Copy link
Member

@stof stof commented Jul 2, 2015

Q A
Bug fix? no
New feature? yes
BC breaks? small one
Deprecations? no
Tests pass? yes
Fixed tickets #13448
License MIT
Doc PR n/a

This allows to release remove references to all services during shutdown, giving much more chances to destruct services and the container through refcounting rather than waiting GC, as it will break cycles between the container and container-aware services.

There is a small BC break for a very edge case: if someone keeps a reference to the container and then shutdowns the kernel, the container would now be cleared and so would not work as intended anymore. But I don't think it is a supported use case. If you shutdown the kernel, the container of this kernel is released by the kernel and should not be used anymore IMO.
Thus, shutting down the kernel generally does not happen except during tests on teardown.

I'm not sure a doc PR is needed here: users of the fullstack framework should never use this feature (the kernel is using it for them). What do you think @weaverryan ?

public function clear()
{
if (!empty($this->scopedServices)) {
throw new RuntimeException('Clearing the container is not allowed when a scope is active.');
Copy link
Member Author

Choose a reason for hiding this comment

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

note that I added this check because if you are calling clear() while a scope is active, we can be totally sure that it is a misuse of the method.

@stof stof force-pushed the clearable_container branch from 3f9eee2 to 715daca Compare July 3, 2015 12:40
@stof
Copy link
Member Author

stof commented Jul 3, 2015

I renamed it to ResettableContainerInterface::reset()

@mickaelandrieu
Copy link
Contributor

I'm not sure a doc PR is needed here: users of the fullstack framework should never use this feature

And others are not aware of it, sadly. Maybe a little section on http://symfony.com/doc/current/components/dependency_injection/introduction.html is enough, what do you think ?

@stof
Copy link
Member Author

stof commented Jul 3, 2015

@mickaelandrieu it does not belong to the introduction IMO, given it is an edge case feature

@Pierstoval
Copy link
Contributor

Maybe this behavior can be used for Testing purpose? When you need to run multiple kernels in a test and check some datas in the container, you may have a reference of it, so clearing the container when shutting the kernel down might be good anyway.

@stof
Copy link
Member Author

stof commented Jul 3, 2015

@Pierstoval I don't understand what you mean

@stof stof changed the title Implement clearable containers Implement resettable containers Jul 3, 2015
@Pierstoval
Copy link
Contributor

For example, when running a phpunit test, one might test compiler passes, so in a single test, he instantiates a first kernel, gets the container and make assertions to check consistency, and then instantiates another kernel, also make assertions on the new container.
In this case, maybe one could keep the container reference even after shutting down the first kernel, so if you clear this reference, no human error is possible when checking the different containers: the first one will be cleared if the associated kernel has been shut down.

I don't know if it's clear enough, but if it's not, then don't mind :p

@stof
Copy link
Member Author

stof commented Jul 3, 2015

@Pierstoval unit testing a compiler pass should not involve booting a kernel (this would be functional testing of the whole app, which is totally inefficient for that).
And anyway, you would still be the one shutting down the kernel if you do it your way. Symfony will not shut down the kernel until the teardown of the WebTestCase.

@weaverryan
Copy link
Member

I don't think we need to doc anything here :)

@stof
Copy link
Member Author

stof commented Jul 3, 2015

yeah, for the few cases where it could be useful to know about it, we can probably tell developers about this feature.

I'm thinking it might maybe benefit Drupal in their testing environment if they recreate a container each time. As they don't use the kernel, they won't benefit form the automatic usage of the feature. but this would be only once they move to 2.8+ though. /cc @Crell

@@ -13,6 +13,7 @@

use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
Copy link
Contributor

Choose a reason for hiding this comment

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

should be added at the alphabetical order

@Tobion
Copy link
Contributor

Tobion commented Jul 3, 2015

👍

@stof stof force-pushed the clearable_container branch from 715daca to 02ab521 Compare July 3, 2015 14:03
public function reset()
{
if (!empty($this->scopedServices)) {
throw new RuntimeException('Resetting the container is not allowed when a scope is active.');
Copy link
Member

Choose a reason for hiding this comment

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

LogicException?

Copy link
Member

Choose a reason for hiding this comment

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

👍

@Nicofuma
Copy link
Contributor

Nicofuma commented Jul 6, 2015

I truly believe it should be documented. Every project using the single components instead of the full stack framework could make use of it and there is some case here it could be very useful.

Maybe an entry in the cookbook? Actually I don't see where it could be in the component documentation... Or just leave it undocumented and rely to the docblock? As you said this feature will not be used by a lot of people.

For the record, phpbb/phpbb:master will make use of it as soon as it will be merged (especially because there is one edge case where we have to build a first container to build the real one (dynamic extension/bundle definition of loading...))

@@ -376,6 +376,18 @@ public function initialized($id)
}

/**
* Clears shared services from the container.
*/
Copy link
Member

Choose a reason for hiding this comment

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

We should definitely document the side effects of calling this method, not only the intended effects (memory) but also the side effects (a shared service will be re-created if get() is called).

@fabpot
Copy link
Member

fabpot commented Jul 14, 2015

@stof Can you address the comments before merging?

@weaverryan
Copy link
Member

@Nicofuma Yea, I was thinking that we rely on the PHP documentation for this. And also, since the Container class itself implements the interface, I figure that most people will use that or at least look at it to see how it works (and then they'll notice that resettable stuff). Happy this will be useful for phpbb :)

@stof stof force-pushed the clearable_container branch from 02ab521 to 1888eff Compare July 21, 2015 15:51
@stof
Copy link
Member Author

stof commented Jul 21, 2015

updated.

Status: needs review

}

/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
Copy link
Member

Choose a reason for hiding this comment

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

Should be LogicException, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

right.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

This allows to remove references to all services during shutdown, giving
much more chances to destruct services and the container through
refcounting rather than waiting GC, as it will break cycles between the
container and container-aware services.
@stof stof force-pushed the clearable_container branch from 1888eff to 4457745 Compare July 22, 2015 08:09
@nicolas-grekas
Copy link
Member

👍

2 similar comments
@theofidry
Copy link
Contributor

👍

@dunglas
Copy link
Member

dunglas commented Jul 22, 2015

👍

@xabbuh
Copy link
Member

xabbuh commented Jul 22, 2015

👍

@stof
Copy link
Member Author

stof commented Jul 22, 2015

FYI, I tried this patch on my work project (I backported the patch on Symfony 2.6 and then ran my Behat testsuite).
Blackfire reports 37% less memory usage, and the time spent in the garbage collector dropped from 37s to 17s (-54%), making the testsuite win several percents of its execution time.
So this is a clear win.

@fabpot
Copy link
Member

fabpot commented Jul 23, 2015

Thank you @stof.

@fabpot fabpot merged commit 4457745 into symfony:2.8 Jul 23, 2015
fabpot added a commit that referenced this pull request Jul 23, 2015
This PR was merged into the 2.8 branch.

Discussion
----------

Implement resettable containers

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | small one
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #13448
| License       | MIT
| Doc PR        | n/a

This allows to release remove references to all services during shutdown, giving much more chances to destruct services and the container through refcounting rather than waiting GC, as it will break cycles between the container and container-aware services.

There is a small BC break for a very edge case: if someone keeps a reference to the container and then shutdowns the kernel, the container would now be cleared and so would not work as intended anymore. But I don't think it is a supported use case. If you shutdown the kernel, the container of this kernel is released by the kernel and should not be used anymore IMO.
Thus, shutting down the kernel generally does not happen except during tests on teardown.

I'm not sure a doc PR is needed here: users of the fullstack framework should never use this feature (the kernel is using it for them). What do you think @weaverryan ?

Commits
-------

4457745 Implement resettable containers
@stof stof deleted the clearable_container branch July 23, 2015 09:48
@fabpot fabpot mentioned this pull request Nov 16, 2015
fabpot added a commit that referenced this pull request Nov 23, 2015
…e/Test/KernelTestCase (nicolas-grekas)

This PR was merged into the 2.8 branch.

Discussion
----------

[HttpKernel] Don't reset on shutdown but in FrameworkBundle/Test/KernelTestCase

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

While trying to migrate Blackfire to 2.8-beta, I found this BC-break: by resetting the container on kernel shut-down, functional tests are broken when they need to use the container after a call to `$this->client->request()`. Broken because e.g . the session or the profiler state is lost between consecutive requests in the same test, and because a call to $container->get('kernel') throws a synthetic-related exception.

This PR fixes the BC-break by reverting to the <=2.7 behavior (not resetting the container on kernel shut-down), and moving resetting to the KernelTestCase.

Commits
-------

baad4da [HttpKernel] Don't reset on shutdown but in FrameworkBundle/Test/KernelTestCase
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.