mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Implemented WebHooks delivery queue.
Completely removed usage of the RabbitMQ. Queue now based on Redis channels. Worker process now extracted as separate docker container. Base image upgraded to the 1.8.0 version (PHP 7.2.7 and pcntl extension).
This commit is contained in:
110
common/tasks/DeliveryWebHook.php
Normal file
110
common/tasks/DeliveryWebHook.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace common\tasks;
|
||||
|
||||
use GuzzleHttp\Client as GuzzleClient;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\Middleware;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Yii;
|
||||
use yii\queue\RetryableJobInterface;
|
||||
|
||||
class DeliveryWebHook implements RetryableJobInterface {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $secret;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $payloads;
|
||||
|
||||
/**
|
||||
* @return int time to reserve in seconds
|
||||
*/
|
||||
public function getTtr(): int {
|
||||
return 65;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $attempt number
|
||||
* @param \Exception|\Throwable $error from last execute of the job
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canRetry($attempt, $error): bool {
|
||||
if ($attempt >= 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($error instanceof ServerException || $error instanceof ConnectException) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \yii\queue\Queue $queue which pushed and is handling the job
|
||||
*
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function execute($queue): void {
|
||||
$client = $this->createClient();
|
||||
try {
|
||||
$client->request('POST', $this->url, [
|
||||
'headers' => [
|
||||
'User-Agent' => 'Account-Ely-Hookshot/' . Yii::$app->version,
|
||||
'X-Ely-Accounts-Event' => $this->type,
|
||||
],
|
||||
'form_params' => $this->payloads,
|
||||
]);
|
||||
} catch (ClientException $e) {
|
||||
Yii::info("Delivery for {$this->url} has failed with {$e->getResponse()->getStatusCode()} status.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected function createClient(): ClientInterface {
|
||||
return new GuzzleClient([
|
||||
'handler' => $this->createStack(),
|
||||
'timeout' => 60,
|
||||
'connect_timeout' => 10,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function createStack(): HandlerStack {
|
||||
$stack = HandlerStack::create();
|
||||
$stack->push(Middleware::mapRequest(function(RequestInterface $request): RequestInterface {
|
||||
if (empty($this->secret)) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
$payload = (string)$request->getBody();
|
||||
$signature = hash_hmac('sha1', $payload, $this->secret);
|
||||
|
||||
/** @noinspection ExceptionsAnnotatingAndHandlingInspection */
|
||||
return $request->withHeader('X-Hub-Signature', 'sha1=' . $signature);
|
||||
}));
|
||||
|
||||
return $stack;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user