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

Skip to content

Commit 6fd9f6a

Browse files
insidestylessroze
authored andcommitted
[BridgeDoctrineMessenger] Doctrine ping connection middleware
1 parent 713aab7 commit 6fd9f6a

5 files changed

+248
-0
lines changed

src/Symfony/Bridge/Doctrine/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ CHANGELOG
77
* changed guessing of DECIMAL to set the `input` option of `NumberType` to string
88
* deprecated not passing an `IdReader` to the `DoctrineChoiceLoader` when query can be optimized with a single id field
99
* deprecated passing an `IdReader` to the `DoctrineChoiceLoader` when entities have a composite id
10+
* added `DoctrinePingConnectionMiddleware`
11+
* added `DoctrineCloseConnectionMiddleware`
1012

1113
4.2.0
1214
-----
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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\Messenger;
13+
14+
use Doctrine\Common\Persistence\ManagerRegistry;
15+
use Doctrine\ORM\EntityManagerInterface;
16+
use Symfony\Component\Messenger\Envelope;
17+
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
18+
use Symfony\Component\Messenger\Middleware\StackInterface;
19+
20+
/**
21+
* Closes connection and therefore saves number of connections.
22+
*
23+
* @author Fuong <[email protected]>
24+
*
25+
* @experimental in 4.3
26+
*/
27+
class DoctrineCloseConnectionMiddleware implements MiddlewareInterface
28+
{
29+
private $managerRegistry;
30+
private $entityManagerName;
31+
32+
public function __construct(ManagerRegistry $managerRegistry, string $entityManagerName = null)
33+
{
34+
$this->managerRegistry = $managerRegistry;
35+
$this->entityManagerName = $entityManagerName;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function handle(Envelope $envelope, StackInterface $stack): Envelope
42+
{
43+
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
44+
45+
if (!$entityManager instanceof EntityManagerInterface) {
46+
throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName));
47+
}
48+
49+
try {
50+
$connection = $entityManager->getConnection();
51+
52+
return $stack->next()->handle($envelope, $stack);
53+
} finally {
54+
$connection->close();
55+
}
56+
}
57+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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\Messenger;
13+
14+
use Doctrine\Common\Persistence\ManagerRegistry;
15+
use Doctrine\ORM\EntityManagerInterface;
16+
use Symfony\Component\Messenger\Envelope;
17+
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
18+
use Symfony\Component\Messenger\Middleware\StackInterface;
19+
20+
/**
21+
* Checks whether the connection is still open or reconnects otherwise.
22+
*
23+
* @author Fuong <[email protected]>
24+
*
25+
* @experimental in 4.3
26+
*/
27+
class DoctrinePingConnectionMiddleware implements MiddlewareInterface
28+
{
29+
private $managerRegistry;
30+
private $entityManagerName;
31+
32+
public function __construct(ManagerRegistry $managerRegistry, string $entityManagerName = null)
33+
{
34+
$this->managerRegistry = $managerRegistry;
35+
$this->entityManagerName = $entityManagerName;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function handle(Envelope $envelope, StackInterface $stack): Envelope
42+
{
43+
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
44+
45+
if (!$entityManager instanceof EntityManagerInterface) {
46+
throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName));
47+
}
48+
49+
$connection = $entityManager->getConnection();
50+
51+
if (!$connection->ping()) {
52+
$connection->close();
53+
$connection->connect();
54+
}
55+
56+
if (!$entityManager->isOpen()) {
57+
$this->managerRegistry->resetManager($this->entityManagerName);
58+
}
59+
60+
return $stack->next()->handle($envelope, $stack);
61+
}
62+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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\Tests\Messenger;
13+
14+
use Doctrine\Common\Persistence\ManagerRegistry;
15+
use Doctrine\DBAL\Connection;
16+
use Doctrine\ORM\EntityManagerInterface;
17+
use Symfony\Bridge\Doctrine\Messenger\DoctrineCloseConnectionMiddleware;
18+
use Symfony\Component\Messenger\Envelope;
19+
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
20+
21+
class DoctrineCloseConnectionMiddlewareTest extends MiddlewareTestCase
22+
{
23+
private $connection;
24+
private $entityManager;
25+
private $managerRegistry;
26+
private $middleware;
27+
private $entityManagerName = 'default';
28+
29+
protected function setUp()
30+
{
31+
$this->connection = $this->createMock(Connection::class);
32+
33+
$this->entityManager = $this->createMock(EntityManagerInterface::class);
34+
$this->entityManager->method('getConnection')->willReturn($this->connection);
35+
36+
$this->managerRegistry = $this->createMock(ManagerRegistry::class);
37+
$this->managerRegistry->method('getManager')->willReturn($this->entityManager);
38+
39+
$this->middleware = new DoctrineCloseConnectionMiddleware(
40+
$this->managerRegistry,
41+
$this->entityManagerName
42+
);
43+
}
44+
45+
public function testMiddlewareCloseConnection()
46+
{
47+
$this->connection->expects($this->once())
48+
->method('close')
49+
;
50+
51+
$this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock());
52+
}
53+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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\Tests\Messenger;
13+
14+
use Doctrine\Common\Persistence\ManagerRegistry;
15+
use Doctrine\DBAL\Connection;
16+
use Doctrine\ORM\EntityManagerInterface;
17+
use Symfony\Bridge\Doctrine\Messenger\DoctrinePingConnectionMiddleware;
18+
use Symfony\Component\Messenger\Envelope;
19+
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
20+
21+
class DoctrinePingConnectionMiddlewareTest extends MiddlewareTestCase
22+
{
23+
private $connection;
24+
private $entityManager;
25+
private $managerRegistry;
26+
private $middleware;
27+
private $entityManagerName = 'default';
28+
29+
protected function setUp()
30+
{
31+
$this->connection = $this->createMock(Connection::class);
32+
33+
$this->entityManager = $this->createMock(EntityManagerInterface::class);
34+
$this->entityManager->method('getConnection')->willReturn($this->connection);
35+
36+
$this->managerRegistry = $this->createMock(ManagerRegistry::class);
37+
$this->managerRegistry->method('getManager')->willReturn($this->entityManager);
38+
39+
$this->middleware = new DoctrinePingConnectionMiddleware(
40+
$this->managerRegistry,
41+
$this->entityManagerName
42+
);
43+
}
44+
45+
public function testMiddlewarePingOk()
46+
{
47+
$this->connection->expects($this->once())
48+
->method('ping')
49+
->willReturn(false);
50+
51+
$this->connection->expects($this->once())
52+
->method('close')
53+
;
54+
$this->connection->expects($this->once())
55+
->method('connect')
56+
;
57+
58+
$this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock());
59+
}
60+
61+
public function testMiddlewarePingResetEntityManager()
62+
{
63+
$this->entityManager->expects($this->once())
64+
->method('isOpen')
65+
->willReturn(false)
66+
;
67+
$this->managerRegistry->expects($this->once())
68+
->method('resetManager')
69+
->with($this->entityManagerName)
70+
;
71+
72+
$this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock());
73+
}
74+
}

0 commit comments

Comments
 (0)