Рейтинг:0

Добавление Middleware::retry() к пользовательскому httpClient влияет на http_client по умолчанию.

флаг nl

У нас есть два 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;
    };
  }
Рейтинг:1
флаг vg

Мне кажется, как путем изменения впрыснутого $стек, вы влияете на значение по умолчанию.

Попробуйте создать новый с HandlerStack::создать(); или клонируйте $stack, который вы вводите, с помощью $mystack = клонировать $stack;

Существует также onHandlerStack событие, которое вы могли бы подать, исходя из «чего», я не могу вам сказать;)

Michael Chen avatar
флаг nl
Да, я проверил это, и это сработало! После вашего предложения я просмотрел [документ] guzzle (https://docs.guzzlephp.org/en/stable/handlers-and-middleware.html#handlerstack) и vuala! Спасибо! Вставка рабочего кода ниже. ```php $newStack = HandlerStack::create(); $newStack->push(Middleware::retry($this->retryDecider(), $this->retryDelay())); $this->wvtClient = $http_client_factory->fromOptions([ 'обработчик' => $ новый стек, 'тайм-аут' => 20, ]); ```

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.