Skip to content

Instantly share code, notes, and snippets.

@janklan
Created April 20, 2022 00:59
Show Gist options
  • Save janklan/6979d87124e2287ce6b3878bebf837b5 to your computer and use it in GitHub Desktop.
Save janklan/6979d87124e2287ce6b3878bebf837b5 to your computer and use it in GitHub Desktop.
BatchHandlerInterface example that accepts or rejects an entire batch
<?php
namespace App\Message;
final class RateUpdate
{
public readonly string $start;
public readonly string $end;
/**
* @param int $rateId
* @param float|null $value
* @param \DateTimeImmutable $startDate
* @param \DateTimeImmutable|null $endDate
* @param array $weekdays List of week days within the start-end range that this rate should apply to
*/
public function __construct(
public readonly int $rateId,
public readonly ?float $value,
\DateTimeImmutable $startDate,
?\DateTimeImmutable $endDate = null,
public readonly array $weekdays = [],
) {
$this->start = $startDate->format('Y-m-d');
$this->end = $endDate?->format('Y-m-d') ?: $this->start;
}
}
<?php
namespace App\MessageHandler;
use App\Message\RateUpdate;
use Symfony\Component\Messenger\Handler\Acknowledger;
use Symfony\Component\Messenger\Handler\BatchHandlerInterface;
use Symfony\Component\Messenger\Handler\BatchHandlerTrait;
use Symfony\Contracts\HttpClient\HttpClientInterface;
final class RateUpdateHandler implements BatchHandlerInterface
{
use BatchHandlerTrait;
public function __construct(public readonly HttpClientInterface $prenoClient)
{
}
/**
* @param RateUpdate $message Each RateUpdate contains all the data to update one object via the API. The API supports batch update of multiple objects.
* @param Acknowledger|null $ack
*/
public function __invoke(RateUpdate $message, Acknowledger $ack = null)
{
return $this->handle($message, $ack);
}
/**
* @param array $jobs A list of RateUpdate DTOs that can be merged into a single REST API PUT call
*/
private function process(array $jobs): void
{
try {
/**
* @var RateUpdate $message
* @var Acknowledger $ack
*/
$body = [];
foreach ($jobs as [$message, $ack]) {
$body[] = [
'rate_id' => $message->rateId,
'value' => $message->value,
'start' => $message->start,
'end' => $message->end,
'weekdays' => $message->weekdays
];
}
$response = $this->prenoClient->request('PUT', 'rates', [
'body' => json_encode($body, JSON_THROW_ON_ERROR)
])->getContent();
foreach ($jobs as [$message, $ack]) {
$ack->ack($response);
}
} catch (\Throwable $error) {
foreach ($jobs as [$message, $ack]) {
$ack->nack($error);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment