Skip to content

Commit 7791eb2

Browse files
committed
[DoctrineBridge] doctrine connection listener for long running runtime
1 parent 014bfac commit 7791eb2

File tree

4 files changed

+132
-17
lines changed

4 files changed

+132
-17
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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;
13+
14+
use Doctrine\DBAL\Connection;
15+
use Doctrine\DBAL\Exception as DBALException;
16+
17+
class CheckConnection
18+
{
19+
public static function checkConnection(Connection $connection) {
20+
try {
21+
$connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
22+
} catch (DBALException) {
23+
$connection->close();
24+
// Attempt to reestablish the lazy connection by sending another query.
25+
$connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
26+
}
27+
}
28+
}

src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111

1212
namespace Symfony\Bridge\Doctrine\Messenger;
1313

14-
use Doctrine\DBAL\Connection;
15-
use Doctrine\DBAL\Exception as DBALException;
1614
use Doctrine\ORM\EntityManagerInterface;
15+
use Symfony\Bridge\Doctrine\CheckConnection;
1716
use Symfony\Component\Messenger\Envelope;
1817
use Symfony\Component\Messenger\Middleware\StackInterface;
1918
use Symfony\Component\Messenger\Stamp\ConsumedByWorkerStamp;
@@ -38,24 +37,10 @@ private function pingConnection(EntityManagerInterface $entityManager): void
3837
{
3938
$connection = $entityManager->getConnection();
4039

41-
try {
42-
$this->executeDummySql($connection);
43-
} catch (DBALException) {
44-
$connection->close();
45-
// Attempt to reestablish the lazy connection by sending another query.
46-
$this->executeDummySql($connection);
47-
}
40+
CheckConnection::checkConnection($connection);
4841

4942
if (!$entityManager->isOpen()) {
5043
$this->managerRegistry->resetManager($this->entityManagerName);
5144
}
5245
}
53-
54-
/**
55-
* @throws DBALException
56-
*/
57-
private function executeDummySql(Connection $connection): void
58-
{
59-
$connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL());
60-
}
6146
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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\Middleware;
13+
14+
use Doctrine\DBAL\Connection;
15+
use Doctrine\DBAL\Driver;
16+
use Doctrine\DBAL\Driver\Connection as DriverConnection;
17+
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
18+
use Doctrine\ORM\EntityManagerInterface;
19+
use Doctrine\Persistence\ManagerRegistry;
20+
use Symfony\Bridge\Doctrine\CheckConnection;
21+
use Symfony\Component\DependencyInjection\ContainerInterface;
22+
23+
class DoctrineConnectionDriver extends AbstractDriverMiddleware
24+
{
25+
public function __construct(private Driver $driver, private readonly ManagerRegistry $managerRegistry, private readonly ContainerInterface $container)
26+
{
27+
parent::__construct($driver);
28+
}
29+
30+
public function connect(array $params): DriverConnection
31+
{
32+
$connectionServices = $this->managerRegistry->getConnectionNames();
33+
34+
foreach ($connectionServices as $connectionServiceName) {
35+
if (!$this->container->initialized($connectionServiceName)) {
36+
continue;
37+
}
38+
39+
$connection = $this->container->get($connectionServiceName);
40+
41+
if (!$connection instanceof Connection) {
42+
continue;
43+
}
44+
45+
if ($connection->isConnected()) {
46+
CheckConnection::checkConnection($connection);
47+
}
48+
49+
$managerNames = $this->managerRegistry->getManagerNames();
50+
51+
foreach ($managerNames as $managerName) {
52+
if (!$this->container->initialized($managerName)) {
53+
continue;
54+
}
55+
56+
$manager = $this->container->get($managerName);
57+
58+
if (!$manager instanceof EntityManagerInterface) {
59+
continue;
60+
}
61+
62+
if (!$manager->isOpen()) {
63+
$this->managerRegistry->resetManager($managerName);
64+
}
65+
}
66+
}
67+
68+
return parent::connect($params);
69+
}
70+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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\Middleware;
13+
14+
use Doctrine\DBAL\Driver;
15+
use Doctrine\DBAL\Driver\Middleware;
16+
use Doctrine\Persistence\ManagerRegistry;
17+
use Symfony\Component\DependencyInjection\ContainerInterface;
18+
19+
/**
20+
* Based on https://github.com/Baldinof/roadrunner-bundle/blob/3.x/src/Integration/Doctrine/DoctrineORMMiddleware.php.
21+
*/
22+
class DoctrineConnectionMiddleware implements Middleware
23+
{
24+
public function __construct(private ManagerRegistry $managerRegistry, private ContainerInterface $container)
25+
{
26+
}
27+
28+
public function wrap(Driver $driver): Driver
29+
{
30+
return new DoctrineConnectionDriver($driver, $this->managerRegistry, $this->container);
31+
}
32+
}

0 commit comments

Comments
 (0)