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

Skip to content

Commit ba1eefd

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

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-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: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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 DoctrineConnectionListener 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('Is not an instance of "%s".', Connection::class));
49+
}
50+
51+
if ($connection->isConnected() && false === $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('Is not an instance of "%s".', EntityManagerInterface::class));
66+
}
67+
68+
if ($manager instanceof LazyLoadingInterface) {
69+
continue; // Doctrine bundle will handle manager reset on next request
70+
}
71+
72+
if ($manager instanceof LazyObjectInterface) {
73+
continue; // Doctrine bundle will handle manager reset on next request
74+
}
75+
76+
if (!$manager->isOpen()) {
77+
$this->eventDispatcher->dispatch(new ForceKernelRebootEvent(
78+
"entity manager '$managerName' is closed and the package `symfony/proxy-manager-bridge` is not installed so kernel reset will not re-open it"
79+
));
80+
81+
return;
82+
}
83+
}
84+
}
85+
}
86+
87+
private function ping(Connection $con): bool
88+
{
89+
try {
90+
$con->executeQuery($con->getDatabasePlatform()->getDummySelectSQL());
91+
92+
return true;
93+
} catch (DBALException $e) {
94+
return false;
95+
}
96+
}
97+
98+
public static function getSubscribedEvents(): array
99+
{
100+
return [
101+
KernelEvents::REQUEST => 'onKernelRequest',
102+
];
103+
}
104+
}

0 commit comments

Comments
 (0)