From 6fd9f6a859f0efef1e0b9163e963dbb56e41250d Mon Sep 17 00:00:00 2001 From: insidestyles Date: Thu, 11 Apr 2019 15:11:21 +0300 Subject: [PATCH] [BridgeDoctrineMessenger] Doctrine ping connection middleware --- src/Symfony/Bridge/Doctrine/CHANGELOG.md | 2 + .../DoctrineCloseConnectionMiddleware.php | 57 ++++++++++++++ .../DoctrinePingConnectionMiddleware.php | 62 ++++++++++++++++ .../DoctrineCloseConnectionMiddlewareTest.php | 53 +++++++++++++ .../DoctrinePingConnectionMiddlewareTest.php | 74 +++++++++++++++++++ 5 files changed, 248 insertions(+) create mode 100644 src/Symfony/Bridge/Doctrine/Messenger/DoctrineCloseConnectionMiddleware.php create mode 100644 src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineCloseConnectionMiddlewareTest.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php diff --git a/src/Symfony/Bridge/Doctrine/CHANGELOG.md b/src/Symfony/Bridge/Doctrine/CHANGELOG.md index 3bcf9a77dfe56..3fdbe4fb1113c 100644 --- a/src/Symfony/Bridge/Doctrine/CHANGELOG.md +++ b/src/Symfony/Bridge/Doctrine/CHANGELOG.md @@ -7,6 +7,8 @@ CHANGELOG * changed guessing of DECIMAL to set the `input` option of `NumberType` to string * deprecated not passing an `IdReader` to the `DoctrineChoiceLoader` when query can be optimized with a single id field * deprecated passing an `IdReader` to the `DoctrineChoiceLoader` when entities have a composite id + * added `DoctrinePingConnectionMiddleware` + * added `DoctrineCloseConnectionMiddleware` 4.2.0 ----- diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineCloseConnectionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineCloseConnectionMiddleware.php new file mode 100644 index 0000000000000..6520ac0a35952 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineCloseConnectionMiddleware.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Messenger; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Middleware\MiddlewareInterface; +use Symfony\Component\Messenger\Middleware\StackInterface; + +/** + * Closes connection and therefore saves number of connections. + * + * @author Fuong + * + * @experimental in 4.3 + */ +class DoctrineCloseConnectionMiddleware implements MiddlewareInterface +{ + private $managerRegistry; + private $entityManagerName; + + public function __construct(ManagerRegistry $managerRegistry, string $entityManagerName = null) + { + $this->managerRegistry = $managerRegistry; + $this->entityManagerName = $entityManagerName; + } + + /** + * {@inheritdoc} + */ + public function handle(Envelope $envelope, StackInterface $stack): Envelope + { + $entityManager = $this->managerRegistry->getManager($this->entityManagerName); + + if (!$entityManager instanceof EntityManagerInterface) { + throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName)); + } + + try { + $connection = $entityManager->getConnection(); + + return $stack->next()->handle($envelope, $stack); + } finally { + $connection->close(); + } + } +} diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php new file mode 100644 index 0000000000000..021d7a8392065 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Messenger; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Middleware\MiddlewareInterface; +use Symfony\Component\Messenger\Middleware\StackInterface; + +/** + * Checks whether the connection is still open or reconnects otherwise. + * + * @author Fuong + * + * @experimental in 4.3 + */ +class DoctrinePingConnectionMiddleware implements MiddlewareInterface +{ + private $managerRegistry; + private $entityManagerName; + + public function __construct(ManagerRegistry $managerRegistry, string $entityManagerName = null) + { + $this->managerRegistry = $managerRegistry; + $this->entityManagerName = $entityManagerName; + } + + /** + * {@inheritdoc} + */ + public function handle(Envelope $envelope, StackInterface $stack): Envelope + { + $entityManager = $this->managerRegistry->getManager($this->entityManagerName); + + if (!$entityManager instanceof EntityManagerInterface) { + throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName)); + } + + $connection = $entityManager->getConnection(); + + if (!$connection->ping()) { + $connection->close(); + $connection->connect(); + } + + if (!$entityManager->isOpen()) { + $this->managerRegistry->resetManager($this->entityManagerName); + } + + return $stack->next()->handle($envelope, $stack); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineCloseConnectionMiddlewareTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineCloseConnectionMiddlewareTest.php new file mode 100644 index 0000000000000..3036b42593401 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineCloseConnectionMiddlewareTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Messenger; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\DBAL\Connection; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Bridge\Doctrine\Messenger\DoctrineCloseConnectionMiddleware; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase; + +class DoctrineCloseConnectionMiddlewareTest extends MiddlewareTestCase +{ + private $connection; + private $entityManager; + private $managerRegistry; + private $middleware; + private $entityManagerName = 'default'; + + protected function setUp() + { + $this->connection = $this->createMock(Connection::class); + + $this->entityManager = $this->createMock(EntityManagerInterface::class); + $this->entityManager->method('getConnection')->willReturn($this->connection); + + $this->managerRegistry = $this->createMock(ManagerRegistry::class); + $this->managerRegistry->method('getManager')->willReturn($this->entityManager); + + $this->middleware = new DoctrineCloseConnectionMiddleware( + $this->managerRegistry, + $this->entityManagerName + ); + } + + public function testMiddlewareCloseConnection() + { + $this->connection->expects($this->once()) + ->method('close') + ; + + $this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock()); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php new file mode 100644 index 0000000000000..cc15625227983 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Messenger; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\DBAL\Connection; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Bridge\Doctrine\Messenger\DoctrinePingConnectionMiddleware; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase; + +class DoctrinePingConnectionMiddlewareTest extends MiddlewareTestCase +{ + private $connection; + private $entityManager; + private $managerRegistry; + private $middleware; + private $entityManagerName = 'default'; + + protected function setUp() + { + $this->connection = $this->createMock(Connection::class); + + $this->entityManager = $this->createMock(EntityManagerInterface::class); + $this->entityManager->method('getConnection')->willReturn($this->connection); + + $this->managerRegistry = $this->createMock(ManagerRegistry::class); + $this->managerRegistry->method('getManager')->willReturn($this->entityManager); + + $this->middleware = new DoctrinePingConnectionMiddleware( + $this->managerRegistry, + $this->entityManagerName + ); + } + + public function testMiddlewarePingOk() + { + $this->connection->expects($this->once()) + ->method('ping') + ->willReturn(false); + + $this->connection->expects($this->once()) + ->method('close') + ; + $this->connection->expects($this->once()) + ->method('connect') + ; + + $this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock()); + } + + public function testMiddlewarePingResetEntityManager() + { + $this->entityManager->expects($this->once()) + ->method('isOpen') + ->willReturn(false) + ; + $this->managerRegistry->expects($this->once()) + ->method('resetManager') + ->with($this->entityManagerName) + ; + + $this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock()); + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy