Skip to content

[Config][DI] Add ComposerResource to track the runtime engine + deps #21505

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
Feb 12, 2017

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Feb 2, 2017

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

So that the container is invalidated whenever a new PHP runtime is used, a PHP-extension is added, or vendors are changed.

self::$globalVersions = array();

foreach (get_loaded_extensions() as $ext) {
self::$globalVersions[$ext] = phpversion($ext);
Copy link
Member

Choose a reason for hiding this comment

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

should we also add the PHP version ?

Copy link
Member Author

Choose a reason for hiding this comment

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

it's already there, because among the extensions, there is always "Core", which holds the php version

Copy link
Member

Choose a reason for hiding this comment

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

then OK.

$r = new \ReflectionClass($class);
$v = dirname(dirname($r->getFileName())).DIRECTORY_SEPARATOR;
if (file_exists($v.'composer/installed.json')) {
self::$globalVendors[$v] = @filemtime($v);
Copy link
Member

Choose a reason for hiding this comment

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

IMO, we should rather hash the file. If you rerun composer install, the file will be touched by composer even when there is no change

Copy link
Member Author

Choose a reason for hiding this comment

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

When the file is touched, we'd better recompute the container once rather than compute the hash again and again IMHO

Copy link
Member

@javiereguiluz javiereguiluz left a comment

Choose a reason for hiding this comment

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

👍

namespace Symfony\Component\Config\Resource;

/**
* ComposerResource tracks the PHP version and composer dependencies.
Copy link
Member

Choose a reason for hiding this comment

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

composer -> Composer

private $versions;
private $vendors;

private static $globalVersions;
Copy link
Member

Choose a reason for hiding this comment

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

I don't like the name of these variables. What about $existingVersions or $installedVersions ? (same for the $globalVendors var).

Copy link
Member Author

Choose a reason for hiding this comment

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

change to $runtimeVersions & $runtimeVendors

@nicolas-grekas
Copy link
Member Author

Any files in vendors are now excluded from tracking, transferring tracking responsibility to the new ComposerResource. This should save a bunch of checks in practice, thus enhance DX.

@nicolas-grekas nicolas-grekas force-pushed the di-vendor-res branch 2 times, most recently from b7adaad to e930f40 Compare February 3, 2017 12:04
$driver = 'php';
} else {
// add the directory itself as a resource
$container->fileExists($dir);
Copy link
Member

Choose a reason for hiding this comment

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

I would also rather add $dir.'/'.$configPath as a resource, as creating the directory and adding files in it could change the config (adding the whole bundle as a resource when <bundle>/Resources does not exist was a mistake IMO, hurting performance for some people using annotation, and not working fine anyway as it was not detecting the creation of the folder which would change the type)

Copy link
Member Author

@nicolas-grekas nicolas-grekas Feb 3, 2017

Choose a reason for hiding this comment

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

I guess the code is as it is because $configPath can be a glob/missing subdirs, so the loop just removes "glob+sub-dirs" until a real one is found.

@@ -67,7 +66,7 @@ private function updateDefinition(ContainerBuilder $container, $id, Definition $
try {
$m = new \ReflectionFunction($factory);
if (false !== $m->getFileName() && file_exists($m->getFileName())) {
$container->addResource(new FileResource($m->getFileName()));
$container->fileExists($m->getFileName());
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't you replace the file_exists check above instead ?

Copy link
Member Author

Choose a reason for hiding this comment

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

no need: if the file does not exist, we should not track its non-existence

return 'annotation';
// add the closest existing directory as a resource
$resource = $dir.'/'.$configPath;
while (!is_dir($resource)) {
Copy link
Member

Choose a reason for hiding this comment

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

the only way to reach this code now is that one of the glob calls found something, so we are sure that $dir.'/'.$configPath exists (and we need to track both its existence and the addition/removal of files in it)

Copy link
Member Author

@nicolas-grekas nicolas-grekas Feb 3, 2017

Choose a reason for hiding this comment

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

To me, the code change in this file only ensures that only one resource is added. The remaining logic is untouched. I wouldn't change anything else than the double resource issue here.

@stof
Copy link
Member

stof commented Feb 3, 2017

This should save a bunch of checks in practice, thus enhance DX.

have you tried profiling the dev environment of Symfony to see the impact this PR has ?

@nicolas-grekas
Copy link
Member Author

have you tried profiling the dev environment of Symfony to see the impact this PR has ?

no, but it's not hard to say that if you happen to have some bundles, everything config-related in them won't be tracked anymore, thus the gain can be huge (esp since this involves i/o). Add autowiring to the mix, which creates resources for every single service when looking for filling type hints - it's even bigger :)

@greg0ire greg0ire mentioned this pull request Feb 5, 2017
7 tasks
@stof
Copy link
Member

stof commented Feb 7, 2017

@nicolas-grekas could you try profiling it to give numbers ? (blame the mail I receive from the Sensiolabs marketing telling me I need to measure things to be able to optimize them... 😄 )

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Feb 7, 2017

@stof and you were right to ask, because that needed some polishing :)
So, end result on Symfony Demo:

  • var/cache/dev/appDevDebugProjectContainer.php.meta deflates from 239K to 15K
  • performance increases by 15% on the home page (which does almost nothing itself), see Blackfire comparison.

@nicolas-grekas nicolas-grekas force-pushed the di-vendor-res branch 2 times, most recently from 0a834df to 53985cc Compare February 7, 2017 14:36
@nicolas-grekas nicolas-grekas force-pushed the di-vendor-res branch 2 times, most recently from 1738293 to 4e58b34 Compare February 7, 2017 14:40
@fabpot
Copy link
Member

fabpot commented Feb 12, 2017

Thank you @nicolas-grekas.

@fabpot fabpot merged commit a960c76 into symfony:master Feb 12, 2017
fabpot added a commit that referenced this pull request Feb 12, 2017
… engine + deps (nicolas-grekas)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[Config][DI] Add ComposerResource to track the runtime engine + deps

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

So that the container is invalidated whenever a new PHP runtime is used, a PHP-extension is added, or vendors are changed.

Commits
-------

a960c76 [Config][DI] Add ComposerResource to track runtime + vendors
@nicolas-grekas nicolas-grekas deleted the di-vendor-res branch February 14, 2017 15:20
@fabpot fabpot mentioned this pull request May 1, 2017
nicolas-grekas added a commit that referenced this pull request Aug 22, 2017
This PR was merged into the 3.3 branch.

Discussion
----------

[DI] Use GlobResource for non-tracked directories

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

I noticed that some of my excluded directories are still tracked by the container and changes to files inside them make it recompile. This brought me to the `$trackContents || is_dir($path)` line introduced in #21505.

Commits
-------

048eb18 [DI] Use GlobResource for non-tracked directories
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.

5 participants