Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Last active July 14, 2020 11:47
Show Gist options
  • Save vudaltsov/945291b4e8a8800f669d478c8d66e8b8 to your computer and use it in GitHub Desktop.
Save vudaltsov/945291b4e8a8800f669d478c8d66e8b8 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace Infrastructure\Messaging;
use Doctrine\Persistence\ManagerRegistry;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;
use Doctrine\DBAL\Exception\RetryableException;
final class RetryAfterDeadlockMiddleware implements MiddlewareInterface
{
private const DELAY_MICRO_SECONDS = 100_000;
private ManagerRegistry $managerRegistry;
private LoggerInterface $logger;
private ?string $managerName;
public function __construct(ManagerRegistry $managerRegistry, LoggerInterface $logger, ?string $managerName = null)
{
$this->managerRegistry = $managerRegistry;
$this->logger = $logger;
$this->managerName = $managerName;
}
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
try {
return $stack->next()->handle($envelope, $stack);
} catch (RetryableException $exception) {
$this->logger->warning('Deadlock occurred, retrying.', ['exception' => $exception]);
usleep(self::DELAY_MICRO_SECONDS); // тут может быть какая-то более сложная стратегия задержек
$this->managerRegistry->resetManager($this->managerName);
return $stack->next()->handle($envelope, $stack);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment