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

Skip to content

Commit 3ec9cd7

Browse files
committed
[DoctrineBridge] doctrine connection listener for long running runtime
1 parent 727c7ea commit 3ec9cd7

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Event;
13+
14+
use Symfony\Contracts\EventDispatcher\Event;
15+
16+
final class ForceKernelRebootEvent extends Event
17+
{
18+
public function __construct(private string $reason)
19+
{
20+
}
21+
22+
public function getReason(): string
23+
{
24+
return $this->reason;
25+
}
26+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Listener;
13+
14+
use Doctrine\DBAL\Connection;
15+
use Doctrine\DBAL\Exception as DBALException;
16+
use Doctrine\ORM\EntityManagerInterface;
17+
use Doctrine\Persistence\ManagerRegistry;
18+
use ProxyManager\Proxy\LazyLoadingInterface;
19+
use Symfony\Bridge\Doctrine\Event\ForceKernelRebootEvent;
20+
use Symfony\Component\DependencyInjection\ContainerInterface;
21+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
22+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
23+
use Symfony\Component\HttpKernel\Event\RequestEvent;
24+
use Symfony\Component\HttpKernel\KernelEvents;
25+
use Symfony\Component\VarExporter\LazyObjectInterface;
26+
27+
/**
28+
* Based on https://github.com/Baldinof/roadrunner-bundle/blob/3.x/src/Integration/Doctrine/DoctrineORMMiddleware.php.
29+
*/
30+
class DoctrineConnectionSubscriber implements EventSubscriberInterface
31+
{
32+
public function __construct(private ManagerRegistry $managerRegistry, private ContainerInterface $container, private EventDispatcherInterface $eventDispatcher)
33+
{
34+
}
35+
36+
public function onKernelRequest(RequestEvent $event)
37+
{
38+
$connectionServices = $this->managerRegistry->getConnectionNames();
39+
40+
foreach ($connectionServices as $connectionServiceName) {
41+
if (!$this->container->initialized($connectionServiceName)) {
42+
continue;
43+
}
44+
45+
$connection = $this->container->get($connectionServiceName);
46+
47+
if (!$connection instanceof Connection) {
48+
throw new \RuntimeException(sprintf('The value "%s" is not an instance of "%s".', $connection, Connection::class));
49+
}
50+
51+
if ($connection->isConnected() && !$this->ping($connection)) {
52+
$connection->close();
53+
}
54+
55+
$managerNames = $this->managerRegistry->getManagerNames();
56+
57+
foreach ($managerNames as $managerName) {
58+
if (!$this->container->initialized($managerName)) {
59+
continue;
60+
}
61+
62+
$manager = $this->container->get($managerName);
63+
64+
if (!$manager instanceof EntityManagerInterface) {
65+
throw new \RuntimeException(sprintf('The value "%s" not an instance of "%s".', $manager, EntityManagerInterface::class));
66+
}
67+
68+
if ($manager instanceof LazyLoadingInterface || $manager instanceof LazyObjectInterface) {
69+
continue; // Doctrine bundle will handle manager reset on next request
70+
}
71+
72+
if (!$manager->isOpen()) {
73+
$this->eventDispatcher->dispatch(new ForceKernelRebootEvent(
74+
sprintf('Entity manager "%s" is closed and the package `symfony/proxy-manager-bridge` is not installed so kernel reset will not re-open it', $managerName)
75+
));
76+
77+
return;
78+
}
79+
}
80+
}
81+
}
82+
83+
private function ping(Connection $con): bool
84+
{
85+
try {
86+
$con->executeQuery($con->getDatabasePlatform()->getDummySelectSQL());
87+
88+
return true;
89+
} catch (DBALException $e) {
90+
return false;
91+
}
92+
}
93+
94+
public static function getSubscribedEvents(): array
95+
{
96+
return [
97+
KernelEvents::REQUEST => 'onKernelRequest',
98+
];
99+
}
100+
}

0 commit comments

Comments
 (0)