У нас есть два http_clients в нашем пользовательском сервисном файле на __конструкт
, один по умолчанию из Drupal http_client
сервис, еще один пользовательский новый клиент, созданный с использованием http_client_factory
и http_handler_stack
услуги после Функция formOptions.
Пользовательский клиент использовался для реализации механизма повторных попыток guzzle путем нажатия ПО промежуточного слоя::повторить попытку
в текущий стек handler_stack в наших пользовательских сервисах. Но это промежуточное ПО кажется согласованным по умолчанию. HTTP-клиент
а также, в результате чего все клиентские вызовы проходят через повторная попытка решения()
.
суть ссылки
Я хочу разделить эффект промежуточного ПО для обоих клиентов, что мне делать?
Спасибо за то, что делитесь своими знаниями!
/**
* Создает новый объект службы.
*/
общедоступная функция __construct (EntityTypeManagerInterface $entity_type_manager, ClientInterface $http_client, ClientFactory $http_client_factory, HandlerStack $stack, TimeInterface $datetime_time, ConfigFactoryInterface $config_factory) {
$this->entityTypeManager = $entity_type_manager;
$this->datetimeTime = $datetime_time;
$this->configFactory = $config_factory;
$this->httpClient = $http_client;
// Использовать промежуточное программное обеспечение для повторных попыток, чтобы повторить попытку 2 раза, исходя из тайм-аута 20 секунд.
$stack->push(Middleware::retry($this->retryDecider(), $this->retryDelay()));
$this->customClient = $http_client_factory->fromOptions([
'обработчик' => $стек,
'тайм-аут' => 20,
]);
}
/**
* {@inheritdoc}
*/
публичная функция apiRequest($type, $method, массив $data = [], $retry = FALSE) {
$ клиент = $ повторить ? $this->customClient : $this->httpClient;
переключатель ($ метод) {
чехол "ПОСТ":
$result = $client->request('POST', $this->requestUrl . '/' . $type, [
'form_params' => $данные,
'заголовки' => [
'Принять' => 'приложение/x-www-form-urlencoded',
],
]
);
сломать;
случай "ПОЛУЧИТЬ":
$result = $client->request('GET', $this->requestUrl . '/' . $type, [
'запрос' => $данные,
'заголовки' => [
'Принять' => 'приложение/json',
],
]
);
сломать;
чехол "ПАТЧ":
$result = $client->request('PATCH', $this->requestUrl . '/' . $type, [
'form_params' => $данные,
'заголовки' => [
'Принять' => 'приложение/x-www-form-urlencoded',
],
]);
}
$apiRequest = $result->getBody()->getContents();
вернуть json_decode($apiRequest);
}
/**
* Логический определитель повторных попыток для Guzzle.
*/
защищенная функция retryDecider() {
функция возврата (
$ повторных попыток,
Запрос $запрос,
Ответ $ответ = NULL,
$Exception = NULL
) {
если ((0 < $ повторов) && ($ повторов <= 2)) {
$this->getLogger('API')->info('%uniqid SystemAction retryDecider msg="Повторная попытка %повторных попыток"', [
'%uniqid' => $this->uniqid,
'% повторов' => $ повторов,
]);
}
// Ограничить количество попыток до 3.
если ($ повторных попыток >= 2) {
$this->getLogger('API')->info('%uniqid SystemAction retryDecider msg="Попытка повторной попытки для клиента Guzzle"', [
'%uniqid' => $this->uniqid,
]);
вернуть ЛОЖЬ;
}
// Исключения повторного соединения.
если ($exception instanceof ConnectException) {
вернуть ИСТИНА;
}
если ($ ответ) {
// Повторить попытку при ошибках сервера.
если ($ответ->getStatusCode() >= 500) {
вернуть ИСТИНА;
}
}
вернуть ЛОЖЬ;
};
}
/**
* Задержка каждой попытки между попытками запроса.
*/
защищенная функция retryDelay() {
функция возврата ($numberOfRetries) {
вернуть 1000 * $numberOfRetries;
};
}