8000 [DependencyInjection] Revert "Use weak references in the container" by nicolas-grekas · Pull Request #50440 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[DependencyInjection] Revert "Use weak references 8000 in the container" #50440

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
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,15 @@ public function getProxyFactoryCode(Definition $definition, string $id, string $

return <<<EOF
if (true === \$lazyLoad) {
$instantiation \$container->createProxy('$proxyClass', static function () use (\$containerRef) {
return \\$proxyClass::staticProxyConstructor(static function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) use (\$containerRef) {
\$container = \$containerRef->get();
$instantiation \$container->createProxy('$proxyClass', static fn () => \\$proxyClass::staticProxyConstructor(
static function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) use (\$container) {
\$wrappedInstance = $factoryCode;

\$proxy->setProxyInitializer(null);

return true;
});
});
}
));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@ class LazyServiceProjectServiceContainer extends Container
{%a
protected static function getFooService($container, $lazyLoad = true)
{
$containerRef = $container->ref;

if (true === $lazyLoad) {
return $container->services['foo'] = $container->createProxy('stdClass_%s', static function () use ($containerRef) {
return %S\stdClass_%s(static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($containerRef) {
$container = $containerRef->get();
$wrappedInstance = self::getFooService($containerRef->get(), false);
return $container->services['foo'] = $container->createProxy('stdClass_%s', static fn () => %S\stdClass_%s(
static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {
$wrappedInstance = self::getFooService($container, false);

$proxy->setProxyInitializer(null);

return true;
});
});
}
));
}

return new \stdClass();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@
public function getFooService($lazyLoad = true)
{
$container = $this;
$containerRef = \WeakReference::create($this);

if (true === $lazyLoad) {
return $container->privates['foo'] = $container->createProxy('SunnyInterface_1eff735', static function () use ($containerRef) {
return \SunnyInterface_1eff735::staticProxyConstructor(static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($containerRef) {
$container = $containerRef->get();
return $container->privates['foo'] = $container->createProxy('SunnyInterface_1eff735', static fn () => \SunnyInterface_1eff735::staticProxyConstructor(
static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {
$wrappedInstance = $container->getFooService(false);

$proxy->setProxyInitializer(null);

return true;
});
});
}
));
}

return new Symfony\Bridge\ProxyManager\Tests\LazyProxy\PhpDumper\DummyClass();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ public function testGetProxyFactoryCodeForInterface()
public function getFooService(\$lazyLoad = true)
{
\$container = \$this;
\$containerRef = \\WeakReference::create(\$this);

{$factory} return new {$class}();
}
Expand Down
32 changes: 12 additions & 20 deletions src/Symfony/Component/DependencyInjection/ContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/
private array $removedBindingIds = [];

private \WeakReference $containerRef;

private const INTERNAL_TYPES = [
'int' => true,
'float' => true,
Expand Down Expand Up @@ -1064,9 +1062,8 @@ private function createService(Definition $definition, array &$inlineServices, b
$callable[0] instanceof Reference
|| $callable[0] instanceof Definition && !isset($inlineServices[spl_object_hash($callable[0])])
)) {
$containerRef = $this->containerRef ??= \WeakReference::create($this);
$initializer = static function () use ($containerRef, $callable, &$inlineServices) {
return $containerRef->get()->doResolveServices($callable[0], $inlineServices);
$initializer = function () use ($callable, &$inlineServices) {
return $this->doResolveServices($callable[0], $inlineServices);
};

$proxy = eval('return '.LazyClosure::getCode('$initializer', $callable, $definition, $this, $id).';');
Expand All @@ -1079,14 +1076,13 @@ private function createService(Definition $definition, array &$inlineServices, b
if (true === $tryProxy && $definition->isLazy() && ['Closure', 'fromCallable'] !== $definition->getFactory()
&& !$tryProxy = !($proxy = $this->proxyInstantiator ??= new LazyServiceInstantiator()) || $proxy instanceof RealServiceInstantiator
) {
$containerRef = $this->containerRef ??= \WeakReference::create($this);
$proxy = $proxy->instantiateProxy(
$this,
(clone $definition)
->setClass($class)
->setTags(($definition->hasTag('proxy') ? ['proxy' => $parameterBag->resolveValue($definition->getTag('proxy'))] : []) + $definition->getTags()),
$id, static function ($proxy = false) use ($containerRef, $definition, &$inlineServices, $id) {
return $containerRef->get()->createService($definition, $inlineServices, true, $id, $proxy);
$id, function ($proxy = false) use ($definition, &$inlineServices, $id) {
return $this->createService($definition, $inlineServices, true, $id, $proxy);
}
);
$this->shareService($definition, $proxy, $id, $inlineServices);
Expand Down Expand Up @@ -1214,38 +1210,34 @@ private function doResolveServices(mixed $value, array &$inlineServices = [], bo
$value[$k] = $this->doResolveServices($v, $inlineServices, $isConstructorArgument);
}
} elseif ($value instanceof ServiceClosureArgument) {
$containerRef = $this->containerRef ??= \WeakReference::create($this);
$reference = $value->getValues()[0];
$value = static fn () => $containerRef->get()->resolveServices($reference);
$value = fn () => $this->resolveServices($reference);
} elseif ($value instanceof IteratorArgument) {
$containerRef = $this->containerRef ??= \WeakReference::create($this);
$value = new RewindableGenerator(static function () use ($containerRef, $value, &$inlineServices) {
$container = $containerRef->get();
$value = new RewindableGenerator(function () use ($value, &$inlineServices) {
foreach ($value->getValues() as $k => $v) {
foreach (self::getServiceConditionals($v) as $s) {
if (!$container->has($s)) {
if (!$this->has($s)) {
continue 2;
}
}
foreach (self::getInitializedConditionals($v) as $s) {
if (!$container->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
continue 2;
}
}

yield $k => $container->doResolveServices($v, $inlineServices);
yield $k => $this->doResolveServices($v, $inlineServices);
}
}, static function () use ($containerRef, $value): int {
$container = $containerRef->get();
}, function () use ($value): int {
$count = 0;
foreach ($value->getValues() as $v) {
foreach (self::getServiceConditionals($v) as $s) {
if (!$container->has($s)) {
if (!$this->has($s)) {
continue 2;
}
}
foreach (self::getInitializedConditionals($v) as $s) {
if (!$container->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
continue 2;
}
}
Expand Down
51 changes: 10 additions & 41 deletions src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class PhpDumper extends Dumper
private int $variableCount;
private ?\SplObjectStorage $inlinedDefinitions = null;
private ?array $serviceCalls = null;
private array $reservedVariables = ['instance', 'class', 'this', 'container', 'containerRef'];
private array $reservedVariables = ['instance', 'class', 'this', 'container'];
private ExpressionLanguage $expressionLanguage;
private ?string $targetDirRegex = null;
private int $targetDirMaxMatches;
Expand All @@ -87,7 +87,6 @@ class PhpDumper extends Dumper
private array $singleUsePrivateIds = [];
private array $preload = [];
private bool $addGetService = false;
private bool $addContainerRef = false;
private array $locatedIds = [];
private string $serviceLocatorTag;
private array $exportedVariables = [];
Expand Down Expand Up @@ -247,8 +246,8 @@ public function dump(array $options = []): string|array

if ($this->addGetService) {
$code = preg_replace(
"/(\r?\n\r?\n public function __construct.+?\\{\r?\n) ++([^\r\n]++)/s",
"\n protected \Closure \$getService;$1 \$containerRef = $2\n \$this->getService = static function () use (\$containerRef) { return \$containerRef->get()->getService(...\\func_get_args()); };",
"/\r?\n\r?\n public function __construct.+?\\{\r?\n/s",
"\n protected \Closure \$getService;$0",
$code,
1
);
Expand Down Expand Up @@ -862,7 +861,6 @@ private function addService(string $id, Definition $definition): array
} else {
$lazyInitialization = '';
}
$this->addContainerRef = false;

$code = <<<EOF

Expand All @@ -875,7 +873,7 @@ private function addService(string $id, Definition $definition): array

*/
protected static function {$methodName}(\$container$lazyInitialization)
{%container_ref%
{

EOF;

Expand Down Expand Up @@ -921,9 +919,8 @@ protected static function {$methodName}(\$container$lazyInitialization)
}
}
$lazyLoad = $asGhostObject ? '$proxy' : 'false';
$this->addContainerRef = true;

$factoryCode = $asFile ? sprintf('self::do($containerRef->get(), %s)', $lazyLoad) : sprintf('self::%s($containerRef->get(), %s)', $methodName, $lazyLoad);
$factoryCode = $asFile ? sprintf('self::do($container, %s)', $lazyLoad) : sprintf('self::%s($container, %s)', $methodName, $lazyLoad);
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
}

Expand All @@ -945,9 +942,8 @@ protected static function {$methodName}(\$container$lazyInitialization)
if (!$isProxyCandidate && !$definition->isShared()) {
$c = implode("\n", array_map(fn ($line) => $line ? ' '.$line : $line, explode("\n", $c)));
$lazyloadInitialization = $definition->isLazy() ? ', $lazyLoad = true' : '';
$useContainerRef = $this->addContainerRef ? ' use ($containerRef)' : '';

$c = sprintf(" %s = function (\$container%s)%s {\n%s };\n\n return %1\$s(\$container);\n", $factory, $lazyloadInitialization, $useContainerRef, $c);
$c = sprintf(" %s = function (\$container%s) {\n%s };\n\n return %1\$s(\$container);\n", $factory, $lazyloadInitialization, $c);
}

$code .= $c;
Expand All @@ -958,8 +954,6 @@ protected static function {$methodName}(\$container$lazyInitialization)
$this->definitionVariables = $this->inlinedDefinitions = null;
$this->referenceVariables = $this->serviceCalls 10000 = null;

$code = preg_replace('/%container_ref%/', $this->addContainerRef ? "\n \$containerRef = \$container->ref;\n" : '', $code, 1);

return [$file, $code];
}

Expand Down Expand Up @@ -1196,12 +1190,7 @@ private function addNewInstance(Definition $definition, string $return = '', str
$callable[0] instanceof Reference
|| ($callable[0] instanceof Definition && !$this->definitionVariables->contains($callable[0]))
)) {
if (str_contains($initializer = $this->dumpValue($callable[0]), '$container')) {
$this->addContainerRef = true;
$initializer = sprintf('function () use ($containerRef) { $container = $containerRef->get(); return %s; }', $initializer);
} else {
$initializer = 'fn () => '.$initializer;
}
$initializer = 'fn () => '.$this->dumpValue($callable[0]);

return $return.LazyClosure::getCode($initializer, $callable, $definition, $this->container, $id).$tail;
}
Expand Down Expand Up @@ -1268,11 +1257,9 @@ class $class extends $baseClass
private const DEPRECATED_PARAMETERS = [];

protected \$parameters = [];
protected readonly \WeakReference \$ref;

public function __construct()
{
\$this->ref = \WeakReference::create(\$this);

EOF;
$code = str_replace(" private const DEPRECATED_PARAMETERS = [];\n\n", $this->addDeprecatedParameters(), $code);
Expand Down Expand Up @@ -1853,12 +1840,6 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
$attribute = sprintf('#[\Closure(%s)] ', $attribute);
}

if (str_contains($code, '$container')) {
$this->addContainerRef = true;

return sprintf("%sfunction () use (\$containerRef)%s {\n \$container = \$containerRef->get();\n\n return %s;\n }", $attribute, $returnedType, $code);
}

return sprintf('%sfn ()%s => %s', $attribute, $returnedType, $code);
}

Expand All @@ -1867,15 +1848,8 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
return 'new RewindableGenerator(fn () => new \EmptyIterator(), 0)';
}

$this->addContainerRef = true;

$code = [];
$code[] = 'new RewindableGenerator(function () use ($containerRef) {';
$code[] = ' $container = $containerRef->get();';
$code[] = '';

$countCode = [];
$countCode[] = 'function () use ($containerRef) {';
$code[] = 'new RewindableGenerator(function () use ($container) {';

$operands = [0];
foreach ($values as $k => $v) {
Expand All @@ -1888,12 +1862,7 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
}
}

$countCode[] = ' $container = $containerRef->get();';
$countCode[] = '';
$countCode[] = sprintf(' return %s;', implode(' + ', $operands));
$countCode[] = ' }';

$code[] = sprintf(' }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]);
$code[] = sprintf(' }, %s)', \count($operands) > 1 ? 'fn () => '.implode(' + ', $operands) : $operands[0]);

return implode("\n", $code);
}
Expand Down Expand Up @@ -1925,7 +1894,7 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
}
$this->addGetService = true;

return sprintf('new \%s($container->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : '');
return sprintf('new \%s($container->getService ??= $container->getService(...), [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : '');
}
} finally {
[$this->definitionVariables, $this->referenceVariables] = $scope;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
class Symfony_DI_PhpDumper_Test_Autowire_Closure extends Container
{
protected $parameters = [];
protected readonly \WeakReference $ref;

public function __construct()
{
$this->ref = \WeakReference::create($this);
$this->services = $this->privates = [];
$this->methodMap = [
'bar' => 'getBarService',
Expand Down Expand Up @@ -48,13 +46,7 @@ public function isCompiled(): bool
*/
protected static function getBarService($container)
{
$containerRef = $container->ref;

return $container->services['bar'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\LazyClosureConsumer(#[\Closure(name: 'foo', class: 'Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo')] function () use ($containerRef) {
$container = $containerRef->get();

return ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo());
}, ($container->services['baz'] ?? self::getBazService($container)), ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo())->cloneFoo(...), ($container->services['my_callable'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\MyCallable())->__invoke(...));
return $container->services['bar'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\LazyClosureConsumer(#[\Closure(name: 'foo', class: 'Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo')] fn () => ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo()), ($container->services['baz'] ?? self::getBazService($container)), ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo())->cloneFoo(...), ($container->services['my_callable'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\MyCallable())->__invoke(...));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
class Symfony_DI_PhpDumper_Test_Callable_Adapter_Consumer extends Container
{
protected $parameters = [];
protected readonly \WeakReference $ref;

public function __construct()
{
$this->ref = \WeakReference::create($this);
$this->services = $this->privates = [];
$this->methodMap = [
'bar' => 'getBarService',
Expand Down
Loading
0