Init
This commit is contained in:
122
app/Temporal/WebhookDelivery/WebhookDeliveryWorkflow.php
Normal file
122
app/Temporal/WebhookDelivery/WebhookDeliveryWorkflow.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace App\Temporal\WebhookDelivery;
|
||||
|
||||
use Carbon\CarbonInterval;
|
||||
use Temporal\Activity\ActivityOptions;
|
||||
use Temporal\Common\RetryOptions;
|
||||
use Temporal\Workflow;
|
||||
|
||||
class WebhookDeliveryWorkflow implements WebhookDeliveryWorkflowInterface
|
||||
{
|
||||
private array $endpointStatuses = [];
|
||||
private int $totalDelivered = 0;
|
||||
private int $totalFailed = 0;
|
||||
private int $totalDeadLettered = 0;
|
||||
private int $retryCount = 0;
|
||||
|
||||
/** @var WebhookDeliveryActivityInterface */
|
||||
private $deliveryStub;
|
||||
|
||||
/** @var WebhookDeliveryActivityInterface */
|
||||
private $deadLetterStub;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->deliveryStub = Workflow::newActivityStub(
|
||||
WebhookDeliveryActivityInterface::class,
|
||||
ActivityOptions::new()
|
||||
->withStartToCloseTimeout(CarbonInterval::seconds(30))
|
||||
->withRetryOptions(
|
||||
RetryOptions::new()
|
||||
->withMaximumAttempts(3)
|
||||
->withInitialInterval(CarbonInterval::seconds(1))
|
||||
->withBackoffCoefficient(3.0)
|
||||
)
|
||||
);
|
||||
|
||||
$this->deadLetterStub = Workflow::newActivityStub(
|
||||
WebhookDeliveryActivityInterface::class,
|
||||
ActivityOptions::new()
|
||||
->withStartToCloseTimeout(CarbonInterval::seconds(10))
|
||||
->withRetryOptions(
|
||||
RetryOptions::new()->withMaximumAttempts(1)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function deliver(array $payload, array $endpoints, array $simulationConfig = []): \Generator
|
||||
{
|
||||
// Initialize endpoint statuses
|
||||
foreach ($endpoints as $endpoint) {
|
||||
$this->endpointStatuses[$endpoint] = [
|
||||
'status' => 'pending',
|
||||
'attempt' => 0,
|
||||
'responseTime' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
// Fan-out: deliver to all endpoints in parallel
|
||||
$promises = [];
|
||||
foreach ($endpoints as $endpoint) {
|
||||
$this->endpointStatuses[$endpoint]['status'] = 'delivering';
|
||||
|
||||
$promises[$endpoint] = Workflow::async(function () use ($endpoint, $payload, $simulationConfig) {
|
||||
try {
|
||||
$result = yield $this->deliveryStub->deliverToEndpoint($endpoint, $payload, $simulationConfig);
|
||||
return ['endpoint' => $endpoint, 'success' => true, 'result' => (array) $result];
|
||||
} catch (\Throwable $e) {
|
||||
return ['endpoint' => $endpoint, 'success' => false, 'error' => $e->getMessage()];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Collect results from all parallel activities
|
||||
foreach ($promises as $endpoint => $promise) {
|
||||
$outcome = (array) (yield $promise);
|
||||
|
||||
if ($outcome['success']) {
|
||||
$result = $outcome['result'];
|
||||
$this->endpointStatuses[$endpoint] = [
|
||||
'status' => 'delivered',
|
||||
'attempt' => $result['attempt'] ?? 1,
|
||||
'responseTime' => $result['responseTime'] ?? 0,
|
||||
];
|
||||
$this->totalDelivered++;
|
||||
|
||||
$attempt = $result['attempt'] ?? 1;
|
||||
if ($attempt > 1) {
|
||||
$this->retryCount += ($attempt - 1);
|
||||
}
|
||||
} else {
|
||||
$this->endpointStatuses[$endpoint]['status'] = 'failed';
|
||||
$this->totalFailed++;
|
||||
|
||||
// Dead-letter failed deliveries
|
||||
yield $this->deadLetterStub->deadLetter($endpoint, $payload, $outcome['error'] ?? 'Unknown error');
|
||||
$this->endpointStatuses[$endpoint]['status'] = 'dead_lettered';
|
||||
$this->totalDeadLettered++;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => 'completed',
|
||||
'totalDelivered' => $this->totalDelivered,
|
||||
'totalFailed' => $this->totalFailed,
|
||||
'totalDeadLettered' => $this->totalDeadLettered,
|
||||
'retryCount' => $this->retryCount,
|
||||
'endpoints' => $this->endpointStatuses,
|
||||
];
|
||||
}
|
||||
|
||||
public function getDeliveryStatus(): array
|
||||
{
|
||||
return [
|
||||
'totalDelivered' => $this->totalDelivered,
|
||||
'totalFailed' => $this->totalFailed,
|
||||
'totalDeadLettered' => $this->totalDeadLettered,
|
||||
'retryCount' => $this->retryCount,
|
||||
'endpoints' => $this->endpointStatuses,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user