8000 feature #48484 [ProxyManagerBridge] Deprecate the package (nicolas-gr… · symfony/symfony@6dc7330 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6dc7330

Browse files
committed
feature #48484 [ProxyManagerBridge] Deprecate the package (nicolas-grekas)
This PR was merged into the 6.3 branch. Discussion ---------- [ProxyManagerBridge] Deprecate the package | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - The bridge is not needed anymore, we provide lazy services out of the box since 6.2. Commits ------- 52b6fa7 [ProxyManagerBridge] Deprecate the package
2 parents 67cb407 + 52b6fa7 commit 6dc7330

File tree

12 files changed

+213
-42
lines changed

12 files changed

+213
-42
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use ProxyManager\Proxy\LazyLoadingInterface;
16+
use ProxyManager\Proxy\ValueHolderInterface;
17+
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
18+
use Symfony\Bridge\ProxyManager\Tests\LazyProxy\Dumper\PhpDumperTest;
19+
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\DependencyInjection\ContainerInterface;
21+
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
22+
use Symfony\Component\Filesystem\Filesystem;
23+
24+
/**
25+
* @group legacy
26+
*/
27+
class LegacyManagerRegistryTest extends TestCase
28+
{
29+
public static function setUpBeforeClass(): void
30+
{
31+
$test = new PhpDumperTest();
32+
$test->testDumpContainerWithProxyServiceWillShareProxies();
33+
}
34+
35+
public function testResetService()
36+
{
37+
$container = new \LazyServiceProjectServiceContainer();
38+
39+
$registry = new TestManagerRegistry('name', [], ['defaultManager' => 'foo'], 'defaultConnection', 'defaultManager', 'proxyInterfaceName');
40+
$registry->setTestContainer($container);
41+
42+
$foo = $container->get('foo');
43+
$foo->bar = 123;
44+
$this->assertTrue(isset($foo->bar));
45+
46+
$registry->resetManager();
47+
48+
$this->assertSame($foo, $container->get('foo'));
49+
$this->assertObjectNotHasAttribute('bar', $foo);
50+
}
51+
52+
/**
53+
* When performing an entity manager lazy service reset, the reset operations may re-use the container
54+
* to create a "fresh" service: when doing so, it can happen that the "fresh" service is itself a proxy.
55+
*
56+
* Because of that, the proxy will be populated with a wrapped value that is itself a proxy: repeating
57+
* the reset operation keeps increasing this nesting until the application eventually runs into stack
58+
* overflow or memory overflow operations, which can happen for long-running processes that rely on
59+
* services that are reset very often.
60+
*/
61+
public function testResetServiceWillNotNestFurtherLazyServicesWithinEachOther()
62+
{
63+
// This test scenario only applies to containers composed as a set of generated sources
64+
$this->dumpLazyServiceProjectAsFilesServiceContainer();
65+
66+
/** @var ContainerInterface $container */
67+
$container = new \LazyServiceProjectAsFilesServiceContainer();
68+
69+
$registry = new TestManagerRegistry(
70+
'irrelevant',
71+
[],
72+
['defaultManager' => 'foo'],
73+
'irrelevant',
74+
'defaultManager',
75+
'irrelevant'
76+
);
77+
$registry->setTestContainer($container);
78+
79+
$service = $container->get('foo');
80+
81+
self::assertInstanceOf(\stdClass::class, $service);
82+
self::assertInstanceOf(LazyLoadingInterface::class, $service);
83+
self::assertInstanceOf(ValueHolderInterface::class, $service);
84+
self::assertFalse($service->isProxyInitialized());
85+
86+
$service->initializeProxy();
87+
88+
self::assertTrue($container->initialized('foo'));
89+
self::assertTrue($service->isProxyInitialized());
90+
91+
$registry->resetManager();
92+
$service->initializeProxy();
93+
94+
$wrappedValue = $service->getWrappedValueHolderValue();
95+
self::assertInstanceOf(\stdClass::class, $wrappedValue);
96+
self::assertNotInstanceOf(LazyLoadingInterface::class, $wrappedValue);
97+
self::assertNotInstanceOf(ValueHolderInterface::class, $wrappedValue);
98+
}
99+
100+
private function dumpLazyServiceProjectAsFilesServiceContainer()
101+
{
102+
if (class_exists(\LazyServiceProjectAsFilesServiceContainer::class, false)) {
103+
return;
104+
}
105+
106+
$container = new ContainerBuilder();
107+
108+
$container->register('foo', \stdClass::class)
109+
->setPublic(true)
110+
->setLazy(true);
111+
$container->compile();
112+
113+
$fileSystem = new Filesystem();
114+
115+
$temporaryPath = $fileSystem->tempnam(sys_get_temp_dir(), 'symfonyManagerRegistryTest');
116+
$fileSystem->remove($temporaryPath);
117+
$fileSystem->mkdir($temporaryPath);
118+
119+
$dumper = new PhpDumper($container);
120+
121+
$dumper->setProxyDumper(new ProxyDumper());
122+
$containerFiles = $dumper->dump([
123+
'class' => 'LazyServiceProjectAsFilesServiceContainer',
124+
'as_files' => true,
125+
]);
126+
127+
array_walk(
128+
$containerFiles,
129+
static function (string $containerSources, string $fileName) use ($temporaryPath): void {
130+
(new Filesystem())->dumpFile($temporaryPath.'/'.$fileName, $containerSources);
131+
}
132+
);
133+
134+
require $temporaryPath.'/LazyServiceProjectAsFilesServiceContainer.php';
135+
}
136+
}

src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,29 @@
1212
namespace Symfony\Bridge\Doctrine\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use ProxyManager\Proxy\LazyLoadingInterface;
16-
use ProxyManager\Proxy\ValueHolderInterface;
17-
use Symfony\Bridge\Doctrine\ManagerRegistry;
18-
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
19-
use Symfony\Bridge\ProxyManager\Tests\LazyProxy\Dumper\PhpDumperTest;
2015
use Symfony\Component\DependencyInjection\ContainerBuilder;
2116
use Symfony\Component\DependencyInjection\ContainerInterface;
2217
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
2318
use Symfony\Component\Filesystem\Filesystem;
19+
use Symfony\Component\VarExporter\LazyObjectInterface;
2420

2521
class ManagerRegistryTest extends TestCase
2622
{
2723
public static function setUpBeforeClass(): void
2824
{
29-
$test = new PhpDumperTest();
30-
$test->testDumpContainerWithProxyServiceWillShareProxies();
25+
$container = new ContainerBuilder();
26+
27+
$container->register('foo', \stdClass::class)->setPublic(true);
28+
$container->getDefinition('foo')->setLazy(true)->addTag('proxy', ['interface' => \stdClass::class]);
29+
$container->compile();
30+
31+
$dumper = new PhpDumper($container);
32+
eval('?>'.$dumper->dump(['class' => 'LazyServiceDoctrineBridgeContainer']));
3133
}
3234

3335
public function testResetService()
3436
{
35-
$container = new \LazyServiceProjectServiceContainer();
37+
$container = new \LazyServiceDoctrineBridgeContainer();
3638

3739
$registry = new TestManagerRegistry('name', [], ['defaultManager' => 'foo'], 'defaultConnection', 'defaultManager', 'proxyInterfaceName');
3840
$registry->setTestContainer($container);
@@ -59,10 +61,10 @@ public function testResetService()
5961
public function testResetServiceWillNotNestFurtherLazyServicesWithinEachOther()
6062
{
6163
// This test scenario only applies to containers composed as a set of generated sources
62-
$this->dumpLazyServiceProjectAsFilesServiceContainer();
64+
$this->dumpLazyServiceDoctrineBridgeContainerAsFiles();
6365

6466
/** @var ContainerInterface $container */
65-
$container = new \LazyServiceProjectAsFilesServiceContainer();
67+
$container = new \LazyServiceDoctrineBridgeContainerAsFiles();
6668

6769
$registry = new TestManagerRegistry(
6870
'irrelevant',
@@ -77,35 +79,34 @@ public function testResetServiceWillNotNestFurtherLazyServicesWithinEachOther()
7779
$service = $container->get('foo');
7880

7981
self::assertInstanceOf(\stdClass::class, $service);
80-
self::assertInstanceOf(LazyLoadingInterface::class, $service);
81-
self::assertInstanceOf(ValueHolderInterface::class, $service);
82-
self::assertFalse($service->isProxyInitialized());
82+
self::assertInstanceOf(LazyObjectInterface::class, $service);
83+
self::assertFalse($service->isLazyObjectInitialized());
8384

84-
$service->initializeProxy();
85+
$service->initializeLazyObject();
8586

8687
self::assertTrue($container->initialized('foo'));
87-
self::assertTrue($service->isProxyInitialized());
88+
self::assertTrue($service->isLazyObjectInitialized());
8889

8990
$registry->resetManager();
90-
$service->initializeProxy();
91+
$service->initializeLazyObject();
9192

92-
$wrappedValue = $service->getWrappedValueHolderValue();
93+
$wrappedValue = $service->initializeLazyObject();
9394
self::assertInstanceOf(\stdClass::class, $wrappedValue);
94-
self::assertNotInstanceOf(LazyLoadingInterface::class, $wrappedValue);
95-
self::assertNotInstanceOf(ValueHolderInterface::class, $wrappedValue);
95+
self::assertNotInstanceOf(LazyObjectInterface::class, $wrappedValue);
9696
}
9797

98-
private function dumpLazyServiceProjectAsFilesServiceContainer()
98+
private function dumpLazyServiceDoctrineBridgeContainerAsFiles()
9999
{
100-
if (class_exists(\LazyServiceProjectAsFilesServiceContainer::class, false)) {
100+
if (class_exists(\LazyServiceDoctrineBridgeContainerAsFiles::class, false)) {
101101
return;
102102
}
103103

104104
$container = new ContainerBuilder();
105105

106106
$container->register('foo', \stdClass::class)
107107
->setPublic(true)
108-
->setLazy(true);
108+
->setLazy(true)
109+
->addTag('proxy', ['interface' => \stdClass::class]);
109110
$container->compile();
110111

111112
$fileSystem = new Filesystem();
@@ -116,9 +117,8 @@ private function dumpLazyServiceProjectAsFilesServiceContainer()
116117

117118
$dumper = new PhpDumper($container);
118119

119-
$dumper->setProxyDumper(new ProxyDumper());
120120
$containerFiles = $dumper->dump([
121-
'class' => 'LazyServiceProjectAsFilesServiceContainer',
121+
'class' => 'LazyServiceDoctrineBridgeContainerAsFiles',
122122
'as_files' => true,
123123
]);
124124

@@ -129,19 +129,6 @@ static function (string $containerSources, string $fileName) use ($temporaryPath
129129
}
130130
);
131131

132-
require $temporaryPath.'/LazyServiceProjectAsFilesServiceContainer.php';
133-
}
134-
}
135-
136-
class TestManagerRegistry extends ManagerRegistry
137-
{
138-
public function setTestContainer($container)
139-
{
140-
$this->container = $container;
141-
}
142-
143-
public function getAliasNamespace($alias): string
144-
{
145-
return 'Foo';
132+
require $temporaryPath.'/LazyServiceDoctrineBridgeContainerAsFiles.php';
146133
}
147134
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests;
13+
14+
use Symfony\Bridge\Doctrine\ManagerRegistry;
15+
16+
class TestManagerRegistry extends ManagerRegistry
17+
{
18+
public function setTestContainer($container)
19+
{
20+
$this->container = $container;
21+
}
22+
23+
public function getAliasNamespace($alias): string
24+
{
25+
return 'Foo';
26+
}
27+
}

src/Symfony/Bridge/Doctrine/composer.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@
2828
"symfony/stopwatch": "^5.4|^6.0",
2929
"symfony/cache": "^5.4|^6.0",
3030
"symfony/config": "^5.4|^6.0",
31-
"symfony/dependency-injection": "^5.4|^6.0",
31+
"symfony/dependency-injection": "^6.2",
3232
"symfony/form": "^5.4.9|^6.0.9",
3333
"symfony/http-kernel": "^6.2",
3434
"symfony/messenger": "^5.4|^6.0",
3535
"symfony/doctrine-messenger": "^5.4|^6.0",
3636
"symfony/property-access": "^5.4|^6.0",
3737
"symfony/property-info": "^5.4|^6.0",
38-
"symfony/proxy-manager-bridge": "^5.4|^6.0",
3938
"symfony/security-core": "^6.0",
4039
"symfony/expression-language": "^5.4|^6.0",
4140
"symfony/uid": "^5.4|^6.0",
@@ -55,7 +54,7 @@
5554
"doctrine/orm": "<2.7.4",
5655
"phpunit/phpunit": "<5.4.3",
5756
"symfony/cache": "<5.4",
58-
"symfony/dependency-injection": "<5.4",
57+
"symfony/dependency-injection": "<6.2",
5958
"symfony/form": "<5.4",
6059
"symfony/http-kernel": "<6.2",
6160
"symfony/messenger": "<5.4",

src/Symfony/Bridge/ProxyManager/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Deprecate the bridge
8+
49
4.2.0
510
-----
611

src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@
2121
use Symfony\Component\DependencyInjection\Definition;
2222
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
2323

24+
trigger_deprecation('symfony/proxy-manager-bridge', '6.3', 'The "symfony/proxy-manager-bridge" package is deprecated and can be removed from your dependencies.');
25+
2426
/**
2527
* Runtime lazy loading proxy generator.
2628
*
2729
* @author Marco Pivetta <ocramius@gmail.com>
30+
*
31+
* @deprecated since Symfony 6.3
2832
*/
2933
class RuntimeInstantiator implements InstantiatorInterface
3034
{

src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
use Symfony\Component\DependencyInjection\Definition;
1818
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
1919

20+
trigger_deprecation('symfony/proxy-manager-bridge', '6.3', 'The "symfony/proxy-manager-bridge" package is deprecated and can be removed from your dependencies.');
21+
2022
/**
2123
* Generates dumped PHP code of proxies via reflection.
2224
*
2325
* @author Marco Pivetta <ocramius@gmail.com>
2426
*
27+
* @deprecated since Symfony 6.3
28+
*
2529
* @final
2630
*/
2731
class ProxyDumper implements DumperInterface

src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
* with the ProxyManager bridge.
2525
*
2626
* @author Marco Pivetta <ocramius@gmail.com>
27+
*
28+
* @group legacy
2729
*/
2830
class ContainerBuilderTest extends TestCase
2931
{

src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
* with the ProxyManager bridge.
2323
*
2424
* @author Marco Pivetta <ocramius@gmail.com>
25+
*
26+
* @group legacy
2527
*/
2628
class PhpDumperTest extends TestCase
2729
{

src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Instantiator/RuntimeInstantiatorTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
* Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator}.
2323
*
2424
* @author Marco Pivetta <ocramius@gmail.com>
25+
*
26+
* @group legacy
2527
*/
2628
class RuntimeInstantiatorTest extends TestCase
2729
{

src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
* Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper}.
2121
*
2222
* @author Marco Pivetta <ocramius@gmail.com>
23+
*
24+
* @group legacy
2325
*/
2426
class ProxyDumperTest extends TestCase
2527
{

0 commit comments

Comments
 (0)
0