diff --git a/src/Hermes/ListCreatedHandler.php b/src/Hermes/ListCreatedHandler.php index 80d2fd4..2321c32 100644 --- a/src/Hermes/ListCreatedHandler.php +++ b/src/Hermes/ListCreatedHandler.php @@ -38,16 +38,22 @@ public function handle(MessageInterface $message): bool throw new HermesException('unable to handle event: mail_type_id is missing'); } - $list = $this->listsRepository->find($payload['list_id']); + $list = $this->listsRepository->ensure(function () use ($payload) { + return $this->listsRepository->find($payload['list_id']); + }); $page = 1; while ($users = $this->userProvider->list([], $page)) { foreach ($users as $user) { $this->logger->log(LogLevel::INFO, sprintf("Subscribing user: %s (%s).", $user['email'], $user['id'])); if ($list->auto_subscribe) { - $this->userSubscriptionsRepository->subscribeUser($list, $user['id'], $user['email']); + $this->userSubscriptionsRepository->ensure(function () use ($list, $user) { + $this->userSubscriptionsRepository->subscribeUser($list, $user['id'], $user['email']); + }); } else { - $this->userSubscriptionsRepository->unsubscribeUser($list, $user['id'], $user['email']); + $this->userSubscriptionsRepository->ensure(function () use ($list, $user) { + $this->userSubscriptionsRepository->unsubscribeUser($list, $user['id'], $user['email']); + }); } } $page++; diff --git a/src/Hermes/MailgunEventHandler.php b/src/Hermes/MailgunEventHandler.php index bd99b2b..dc66ec5 100644 --- a/src/Hermes/MailgunEventHandler.php +++ b/src/Hermes/MailgunEventHandler.php @@ -43,7 +43,9 @@ public function handle(MessageInterface $message): bool throw new HermesException('unable to handle event: event is missing'); } - $log = $this->logsRepository->findBySenderId($payload['mail_sender_id']); + $log = $this->logsRepository->ensure(function () use ($payload) { + return $this->logsRepository->findBySenderId($payload['mail_sender_id']); + }); if (!$log) { return false; } @@ -51,19 +53,27 @@ public function handle(MessageInterface $message): bool $eventTimestamp = explode('.', (string) $payload['timestamp'])[0]; $date = DateTime::from($eventTimestamp); - $mailgunEvent = $this->logsRepository->mapEvent($payload['event'], $payload['reason']); + $mailgunEvent = $this->logsRepository->ensure(function () use ($payload) { + return $this->logsRepository->mapEvent($payload['event'], $payload['reason']); + }); if (!$mailgunEvent) { return false; } - $this->logsRepository->update($log, [ - $mailgunEvent => $date, - 'updated_at' => new DateTime(), - ]); + $this->logsRepository->ensure(function () use ($log, $mailgunEvent, $date) { + $this->logsRepository->update($log, [ + $mailgunEvent => $date, + 'updated_at' => new DateTime(), + ]); + }); - $column = $this->batchTemplatesRepository->mapEvent($mailgunEvent); + $column = $this->batchTemplatesRepository->ensure(function () use ($mailgunEvent) { + return $this->batchTemplatesRepository->mapEvent($mailgunEvent); + }); if (isset($column)) { - $this->batchTemplatesRepository->incrementColumn($column, $log->mail_template_id, $log->mail_job_batch_id); + $this->batchTemplatesRepository->ensure(function () use ($column, $log) { + $this->batchTemplatesRepository->incrementColumn($column, $log->mail_template_id, $log->mail_job_batch_id); + }); } if ($payload['event'] === 'dropped') { diff --git a/src/Hermes/RedisDriver.php b/src/Hermes/RedisDriver.php index b8aebd8..87fb77e 100644 --- a/src/Hermes/RedisDriver.php +++ b/src/Hermes/RedisDriver.php @@ -125,10 +125,12 @@ public function wait(Closure $callback, array $priorities = []): void $result = $callback($hermesMessage); if (!$result) { - $this->tasksRepository->add( - $hermesMessage, - HermesTasksRepository::STATE_ERROR - ); + $this->tasksRepository->ensure(function () use ($hermesMessage) { + $this->tasksRepository->add( + $hermesMessage, + HermesTasksRepository::STATE_ERROR + ); + }); } $this->incrementProcessedItems(); break; diff --git a/src/Hermes/SendEmailHandler.php b/src/Hermes/SendEmailHandler.php index 04b4bf5..5500376 100644 --- a/src/Hermes/SendEmailHandler.php +++ b/src/Hermes/SendEmailHandler.php @@ -26,7 +26,9 @@ public function __construct( public function handle(MessageInterface $message): bool { $payload = $message->getPayload(); - $mailTemplate = $this->templatesRepository->getByCode($payload['mail_template_code']); + $mailTemplate = $this->templatesRepository->ensure(function () use ($payload) { + return $this->templatesRepository->getByCode($payload['mail_template_code']); + }); if (!$mailTemplate) { Debugger::log("could not load mail template: record with code [{$payload['mail_template_code']}] doesn't exist"); return false; diff --git a/src/Hermes/SubscribeHandler.php b/src/Hermes/SubscribeHandler.php index e9e5fd7..b7bb516 100644 --- a/src/Hermes/SubscribeHandler.php +++ b/src/Hermes/SubscribeHandler.php @@ -53,7 +53,9 @@ public function handle(MessageInterface $message): bool return true; } - $welcomeEmail = $this->mailTypesRepository->find($payload['mail_type_id'])->subscribe_mail_template; + $welcomeEmail = $this->mailTypesRepository->ensure(function () use ($payload) { + return $this->mailTypesRepository->find($payload['mail_type_id'])->subscribe_mail_template; + }); if (!$welcomeEmail) { return true; diff --git a/src/Hermes/TrackNewsletterArticlesHandler.php b/src/Hermes/TrackNewsletterArticlesHandler.php index e751c47..7939d19 100644 --- a/src/Hermes/TrackNewsletterArticlesHandler.php +++ b/src/Hermes/TrackNewsletterArticlesHandler.php @@ -46,7 +46,9 @@ public function handle(MessageInterface $message): bool throw new HermesException('unable to handle event: status is missing'); } - $batch = $this->batchesRepository->find($payload['mail_job_batch_id']); + $batch = $this->batchesRepository->ensure(function () use ($payload) { + return $this->batchesRepository->find($payload['mail_job_batch_id']); + }); if (!$batch) { throw new HermesException('unable to handle event: mail job batch not found'); } @@ -54,7 +56,9 @@ public function handle(MessageInterface $message): bool return true; } - $batchTemplates = $this->batchTemplatesRepository->findByBatchId($batch->id); + $batchTemplates = $this->batchTemplatesRepository->ensure(function () use ($batch) { + return $this->batchTemplatesRepository->findByBatchId($batch->id); + }); foreach ($batchTemplates as $batchTemplate) { preg_match_all('//i', $batchTemplate->mail_template->mail_body_html, $matches); $matches = array_unique($matches[1]); diff --git a/src/Hermes/UnsubscribeDroppedHandler.php b/src/Hermes/UnsubscribeDroppedHandler.php index ba84ac8..4ffe891 100644 --- a/src/Hermes/UnsubscribeDroppedHandler.php +++ b/src/Hermes/UnsubscribeDroppedHandler.php @@ -38,22 +38,29 @@ public function handle(MessageInterface $message): bool { $payload = $message->getPayload(); - $lastEmails = $this->logsRepository - ->getEmailLogs($payload['email']) - ->limit($this->threshold) - ->fetchPairs('id', 'dropped_at'); + $lastEmails = $this->logsRepository->ensure(function () use ($payload) { + return $this->logsRepository + ->getEmailLogs($payload['email']) + ->limit($this->threshold) + ->fetchPairs('id', 'dropped_at'); + }); $droppedEmails = array_filter($lastEmails); if (count($droppedEmails) < $this->threshold) { return true; } - $types = $this->mailTypesRepository->all(); + $types = $this->mailTypesRepository->ensure(function () { + return $this->mailTypesRepository->all(); + }); foreach ($types as $type) { if ($type->locked) { continue; } - $this->userSubscriptionsRepository->unsubscribeEmail($type, $payload['email']); + + $this->userSubscriptionsRepository->ensure(function () use ($type, $payload) { + $this->userSubscriptionsRepository->unsubscribeEmail($type, $payload['email']); + }); } return true; diff --git a/src/Hermes/ValidateCrmEmailHandler.php b/src/Hermes/ValidateCrmEmailHandler.php index 46b4b25..d4fa74b 100644 --- a/src/Hermes/ValidateCrmEmailHandler.php +++ b/src/Hermes/ValidateCrmEmailHandler.php @@ -40,7 +40,9 @@ public function handle(MessageInterface $message): bool return true; } - $log = $this->logsRepository->findBySenderId($payload['mail_sender_id']); + $log = $this->logsRepository->ensure(function () use ($payload) { + return $this->logsRepository->findBySenderId($payload['mail_sender_id']); + }); if (!$log) { return false; } diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index e9be010..9576209 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -3,9 +3,11 @@ namespace Remp\MailerModule\Repositories; +use Closure; use Nette\Caching\Storage; use Nette\Utils\DateTime; use Nette\Database\Context; +use Throwable; class Repository { @@ -50,6 +52,19 @@ public function getDatabase(): Context return $this->database; } + public function ensure(Closure $callback, int $retryTimes = 1) + { + try { + return $callback($this); + } catch (Throwable $e) { + if ($retryTimes === 0) { + throw $e; + } + $this->database->getConnection()->reconnect(); + return $this->ensure($callback, $retryTimes - 1); + } + } + /** * Update updates provided record with given $data array and mutates the provided instance. Operation is logged * to audit log.