Updated NotifyVisitToWebHooks so that it waits for all requests to finish

This commit is contained in:
Alejandro Celaya
2019-12-27 17:07:20 +01:00
parent 562b0a0868
commit 21a3d4b66b
4 changed files with 40 additions and 15 deletions

View File

@@ -10,8 +10,12 @@ use GuzzleHttp\ClientInterface;
use GuzzleHttp\RequestOptions;
use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
use Throwable;
use function Functional\map;
use function Functional\partial_left;
use function GuzzleHttp\Promise\settle;
class NotifyVisitToWebHooks
{
@@ -23,17 +27,21 @@ class NotifyVisitToWebHooks
private $logger;
/** @var array */
private $webhooks;
/** @var ShortUrlDataTransformer */
private $transformer;
public function __construct(
ClientInterface $httpClient,
EntityManagerInterface $em,
LoggerInterface $logger,
array $webhooks
array $webhooks,
array $domainConfig
) {
$this->httpClient = $httpClient;
$this->em = $em;
$this->logger = $logger;
$this->webhooks = $webhooks;
$this->transformer = new ShortUrlDataTransformer($domainConfig);
}
public function __invoke(ShortUrlLocated $shortUrlLocated): void
@@ -51,17 +59,25 @@ class NotifyVisitToWebHooks
$requestOptions = [
RequestOptions::TIMEOUT => 10,
RequestOptions::JSON => $visit->jsonSerialize(),
RequestOptions::JSON => [
'shortUrl' => $this->transformer->transform($visit->getShortUrl(), false),
'visit' => $visit->jsonSerialize(),
],
];
$requestPromises = map($this->webhooks, function (string $webhook) use ($requestOptions, $visitId) {
$logWebhookWarning = function (string $webhook, Throwable $e) use ($visitId): void {
$this->logger->warning('Failed to notify visit with id "{visitId}" to webhook "{webhook}". {e}', [
'visitId' => $visitId,
'webhook' => $webhook,
'e' => $e,
]);
};
$requestPromises = map($this->webhooks, function (string $webhook) use ($requestOptions, $logWebhookWarning) {
$promise = $this->httpClient->requestAsync(RequestMethodInterface::METHOD_POST, $webhook, $requestOptions);
return $promise->otherwise(function () use ($webhook, $visitId) {
// Log failures
$this->logger->warning('Failed to notify visit with id "{visitId}" to "{webhook}" webhook', [
'visitId' => $visitId,
'webhook' => $webhook,
]);
});
return $promise->otherwise(partial_left($logWebhookWarning, $webhook));
});
// Wait for all the promises to finish, ignoring rejections, as in those cases we only want to log the error.
settle($requestPromises)->wait();
}
}