Skip to content

Instantly share code, notes, and snippets.

@Moln
Created December 22, 2022 01:22
Show Gist options
  • Save Moln/2c48e7be047c901a14b198be84b4349a to your computer and use it in GitHub Desktop.
Save Moln/2c48e7be047c901a14b198be84b4349a to your computer and use it in GitHub Desktop.
swoole doctrine orm pool example
<?php
use Doctrine\DBAL\Exception\ConnectionLost;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Swoole\ConnectionPool;
/**
*/
class DoctrineOrmPool extends ConnectionPool
{
private array $time = [];
private LoggerInterface $logger;
public function __construct(callable $constructor, int $size = self::DEFAULT_SIZE, ?LoggerInterface $logger = null)
{
$this->logger = $logger ?? new NullLogger();
parent::__construct($constructor, $size);
}
public function get(float $timeout = -1): EntityManagerInterface
{
$em = parent::get($timeout);
$key = spl_object_hash($em);
// 30s heartbeat
if (($this->time[$key] ?? 0) > time() - 30) {
return $em;
}
while (true) {
$conn = $em->getConnection();
try {
$this->logger->info('[DoctrineOrmPool] Ping');
$conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL());
$this->time[$key] = time();
return $em;
} catch (ConnectionLost $e) {
$this->logger->warning('[DoctrineOrmPool] lost connection: ' . $e->getMessage());
$conn->close();
sleep(1);
}
}
}
/**
* @param EntityManagerInterface $em
* @inheritdoc
*/
public function put($em): void
{
$em->clear();
$this->logger->debug("[DoctrineOrmPool] Clear.");
parent::put($em);
}
}
<?php
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Laminas\Diactoros\Response\JsonResponse;
use Symfony\Component\Serializer\Serializer;
class ExampleHandler implements RequestHandlerInterface
{
public function __construct(
private DoctrineOrmPool $emPool,
private Serializer $serializer
)
{
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
$em = $emPool->get();
$user = $em->find(User::class, $id);
$emPool->put($em);
return new JsonResponse($this->serializer->normalize($user));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment