Skip to content

[DI] Deprecate Container::isFrozen and introduce isCompiled #19673

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
Mar 22, 2017
Merged

[DI] Deprecate Container::isFrozen and introduce isCompiled #19673

merged 1 commit into from
Mar 22, 2017

Conversation

ro0NL
Copy link
Contributor

@ro0NL ro0NL commented Aug 19, 2016

Q A
Branch? "master"
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? yes
Tests pass? yes
Fixed tickets comma-separated list of tickets fixed by the PR, if any
License MIT
Doc PR reference to the documentation PR, if any

This deprecates the concept of freezing a container, implied by Container::isFrozen. However, freezing happens due compilation (Container::compile). So having just isCompiled instead seems more intuitive, and plays along well with ContainerBuilder.

Before/After;

  • Container::isFrozen
    • Checks if the parameter bag is frozen, but is deprecated in 3.2
    • In 4.0 this methods does not exists and can be replaced with getParameterBag() instanceof FrozenParameterBag or isCompiled(). Depending on what you want (to clarify; the behavior is different when passing a frozen bag to the constructor)
  • Container::isCompiled
    • Truly checks if compile() has ran, and is a new feature
  • ContainerBuilder::merge etc.
    • Now uses isCompiled instead of isFrozen, ie. we allow for it till compilation regarding the state of the paramater bag

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 19, 2016

In some ways it was actually compiling (resolving the parameters), as this is also done in a compiler pass. So we can also just go with compile() + isCompiled() on both sides. And deprecate the concept of freezing, which breaks;

Still allowing to compile a already frozen container builder.

@stof
Copy link
Member

stof commented Aug 19, 2016

-1 for renaming compile to freeze. This method is not only about freezing. It is about performing all the compilation steps of the container building (everything done in compiler passes for instance).

@ro0NL ro0NL changed the title [DI] Deprecate Container::compile [DI] Deprecate Container::isFrozen in favor of isCompiled Aug 19, 2016
@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 19, 2016

@stof different approach. WDYT?

@fabpot
Copy link
Member

fabpot commented Aug 19, 2016

I don't understand the problem you are trying to fix here. Can you elaborate? Deprecating something should be taken lightly, so we need to have a very good reason to rename something.

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 19, 2016

It's confusing to mix&match freeze/is-frozen and compile/is-compiled. isFrozen is currently enabled due compilation (ie. we practically have compile/is-frozen). Imo, the parameter bag is frozen; the container compiled.

This exposes a minor code smell in ContainerBuilder where it's additionally tracking state (ContainerBuilder::$compiled) where this is actually the same as checking if it's frozen (ie. compiled). I guess the difference was unclear back then, and you get "better be safe then sorry" changes.

* @return bool true if the container parameter bag are frozen, false otherwise
* @return bool
*/
final public function isCompiled()
Copy link
Contributor Author

@ro0NL ro0NL Aug 19, 2016

Choose a reason for hiding this comment

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

This is now the ought to use method. If you truly want to check for a frozen parameter bag use
getParameterBag() instanceof FrozenParameterBag instead (hence the deprecation).

Besides, this method now guarantees state of compile() as we dont depend on a frozen parameterbag for that anymore (which we can pass to the constructor ;-)).

Now.., i assume the calls to isFrozen in ContainerBuilder (or practically anywhere) are intended as isCompilated. Which is my true point :)

Copy link
Member

Choose a reason for hiding this comment

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

Why making it final? That would be the first method in the class.

@ro0NL ro0NL changed the title [DI] Deprecate Container::isFrozen in favor of isCompiled [DI] Deprecate Container::isFrozen and introduce isCompiled Aug 19, 2016
if ($this->isFrozen()) {
throw new BadMethodCallException('Cannot load from an extension on a frozen container.');
if ($this->isCompiled()) {
throw new BadMethodCallException('Cannot load from an extension on a conpiled container.');
Copy link
Contributor

Choose a reason for hiding this comment

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

compiled

@nicolas-grekas
Copy link
Member

I tend to be sympathetic to deprecating the "frozen" vocabulary on containers. It's been looking strange to me also and the difference is unclear with the "compile" concept. isCompiled looks better.
That may enhance DX, that would be the argument supporting this change.

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 22, 2016

Updated the PhpDumper as well.. it makes sense, but can be unpredictable when you have
new Container<Builder>(new FrozenParameterBag())

What do we expect when dumping this uncompiled (ie. we dont call $container->compile())? Currently the behavior is the same when doning new Container<Builder>(new ParamaterBag())

@ogizanagi
Copy link
Contributor

ogizanagi commented Aug 22, 2016

@ro0NL : As we do not rely anymore on the $this->parameterBag instanceof FrozenParameterBag, I'd say it doesn't matter anymore... But...you'll probably have to check if the parameterBag is frozen in the ContainerBuilder::merge() method before trying to add parameters.

$this->parameterBag->resolve();

$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
if (!$this->parameterBag instanceof FrozenParameterBag) {
Copy link
Member

Choose a reason for hiding this comment

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

This should be removed: changing the object instance of the bag can be seen as a wanted side effect of compiling. Not wrapping a FrozenParameterBag in a FrozenParameterBag looks like an unnecessary optimization to me also.

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 23, 2016

@ogizanagi merging is only allowed before compiling. If you passed a FrozenParameterBag at that point i tend to let it crash (from the paramereter bag side that is).

Not sure what's best for DX here.. crashing or ignoring silently...

@nicolas-grekas any thoughts?

Other then that.. this is ready.

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 23, 2016

Oh and btw... just to be sure; the YAML+XML dumper really depend on a frozen bag right? Due escaping.

@nicolas-grekas
Copy link
Member

Rebase needed to take #19704 into account.

@allflame
Copy link
Contributor

@ro0NL as far as i can see isCompiled will return false for dumped container whether or not container was compiled beforehand

@nicolas-grekas
Copy link
Member

I really don't know if this has a chance to be accepted by the core team, but let's say yes, I think we should go one step further and try deprecating dumping non-compiled containers.
WDYT?

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 24, 2016

@allflame isCompiled depends on compile(). The PHP dumper doesnt compile your container, it''s more or less designed to cover both cases, ie.

  • dump a compiled container(builder)
  • compile a dumped container(builder)

@allflame
Copy link
Contributor

allflame commented Aug 24, 2016

@ro0NL I'm aware of that fact. Let me explain using your own statements:
Since PhpDumper has nothing to do with the compiled status, it shouldn't change it, right?
What I'm trying to say is that if you take your code, compile the container, you will get isCompiled resolving to true (correct), but if you dump it to the file and then create the container from the dumped file, you will get isCompiled resolving to false (incorrect), which is "strange" since you were dumping compiled container.
@nicolas-grekas tbh I'm not using the whole Symfony ecosystem so I cant think of implication this change can have (potential BC issues), but what I'm pretty sure of is that if you don't compile your container the "original" and "dumped" version won't necessarily be the same.

@ro0NL
Copy link
Contributor Author

ro0NL commented Aug 24, 2016

@allflame sorry, you're right #19704 applies to isCompiled as well, i should fix that 👍

About BC, i truly consider this a design flaw and thinkhope the impact is minimal.

@ro0NL
Copy link
Contributor Author

ro0NL commented Dec 20, 2016

Rebased. Still all good :)

@ro0NL
Copy link
Contributor Author

ro0NL commented Dec 29, 2016

I just realized i made a mistake with the latest deprecation: ed5b1d8#diff-f7b23d463cba27ac5e4cb677f2be7623R76

Im talking uncompiled container here, looking at the class it should have been not-frozen container. I really dont mind this tiny semantic. Then again, if we dont do the PR it might be worth updating that instead... sorry :)

$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());

$this->compiled = true;
Copy link
Member

Choose a reason for hiding this comment

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

I'd keep only this line a revert the previous changes in this method, that would prevent any potential BC-related side effect of the change.

* @return bool true if the container parameter bag are frozen, false otherwise
*/
public function isFrozen()
{
@trigger_error(sprintf('The %s() method is deprecated as of 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
Copy link
Member

Choose a reason for hiding this comment

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

we use "since version 3.3" here usually I think

@@ -554,6 +554,10 @@ public function prependExtensionConfig($name, array $config)
*/
public function compile()
{
if ($this->isCompiled()) {
return;
Copy link
Member

Choose a reason for hiding this comment

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

let's remove this change, it just opens a potential BC break to me

@nicolas-grekas
Copy link
Member

👍 with suggested changes

@ro0NL
Copy link
Contributor Author

ro0NL commented Jan 3, 2017

Updated, rebased & waiting for travis.

Cant wait for 4.0 guys 👍

@xabbuh
Copy link
Member

xabbuh commented Jan 11, 2017

@ro0NL Looks like tests fail.

@ro0NL
Copy link
Contributor Author

ro0NL commented Jan 11, 2017

Hm.. looks fixture related, maybe something added in the meanwhile. Ill have a look tonight.

Note to self;

  • Symfony\Component\DependencyInjection\Tests\ContainerTest::testIsFrozen
  • Symfony\Component\DependencyInjection\Tests\Dumper\PhpDumperTest::testClosureProxy

@nicolas-grekas
Copy link
Member

ping @ro0NL

@ro0NL
Copy link
Contributor Author

ro0NL commented Feb 14, 2017

Yes.. ill check it tonight. Focussed on #19668 first.. but that's more or less dealt with now.

@ro0NL
Copy link
Contributor Author

ro0NL commented Feb 14, 2017

All good @nicolas-grekas

@fabpot
Copy link
Member

fabpot commented Mar 22, 2017

LGMT @ro0NL Can you rebase one last time? Thanks.

@ro0NL
Copy link
Contributor Author

ro0NL commented Mar 22, 2017

@fabpot all good.

@fabpot
Copy link
Member

fabpot commented Mar 22, 2017

Thank you @ro0NL.

@fabpot fabpot merged commit 6abd312 into symfony:master Mar 22, 2017
fabpot added a commit that referenced this pull request Mar 22, 2017
…piled (ro0NL)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Deprecate Container::isFrozen and introduce isCompiled

| Q | A |
| --- | --- |
| Branch? | "master" |
| Bug fix? | no |
| New feature? | yes |
| BC breaks? | no |
| Deprecations? | yes |
| Tests pass? | yes |
| Fixed tickets | comma-separated list of tickets fixed by the PR, if any |
| License | MIT |
| Doc PR | reference to the documentation PR, if any |

This deprecates the concept of freezing a container, implied by `Container::isFrozen`. However, freezing happens due compilation (`Container::compile`). So having just `isCompiled` instead seems more intuitive, and plays along well with `ContainerBuilder`.

Before/After;
- `Container::isFrozen`
  - Checks if the parameter bag is frozen, but is deprecated in 3.2
  - In 4.0 this methods does not exists and can be replaced with `getParameterBag() instanceof FrozenParameterBag` _or_ `isCompiled()`. Depending on what you want (to clarify; the behavior is different when passing a frozen bag to the constructor)
- `Container::isCompiled`
  - Truly checks if `compile()` has ran, and is a new feature
- `ContainerBuilder::merge` etc.
  - Now uses `isCompiled` instead of `isFrozen`, ie. we allow for it till compilation regarding the state of the paramater bag

Commits
-------

6abd312 [DI] Deprecate Container::isFrozen and introduce isCompiled
@ro0NL ro0NL deleted the di/separate-compilation branch March 22, 2017 19:03
*/
public function set($id, $service)
{
$id = $this->normalizeId($id);

if ($this->isFrozen() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
if ($this->isCompiled() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
// setting a synthetic service on a frozen container is alright
throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a frozen container is not allowed.', $id));
Copy link
Contributor

Choose a reason for hiding this comment

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

sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id)

basically, s/frozen/compiled, no ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😭

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed with #22112

@nicolas-grekas nicolas-grekas modified the milestones: 3.x, 3.3 Mar 24, 2017
@fabpot fabpot mentioned this pull request May 1, 2017
nicolas-grekas added a commit that referenced this pull request May 21, 2017
This PR was squashed before being merged into the 4.0-dev branch (closes #22763).

Discussion
----------

[DI] Remove deprecated isFrozen()

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | should be
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | symfony/symfony-docs#... <!--highly recommended for new features-->

See #19673

Test failure seems unrelated.

Commits
-------

04b39a3 [DI] Remove deprecated isFrozen()
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.