Faraday: Rety Middleware не запускается после парсера

Созданный на 23 апр. 2021  ·  4Комментарии  ·  Источник: lostisland/faraday

Основная информация

  • Версия Фарадея: 1.4.1
  • Версия Ruby: 2.7.2

Описание проблемы

_NB: Пожалуйста, дайте мне знать, принадлежит ли это к faraday_middleware . Поскольку он включает в себя два промежуточного программного обеспечения, я не знал, где его поставить.

При создании соединения я ожидаю (как указано в документации) промежуточное ПО будет работать в том порядке, в котором оно объявлено. Однако, когда запрос не выполняется и я загружаю промежуточное ПО для анализа :json за которым следует промежуточное ПО :retry , env.body не анализируется в рамках :retry промежуточного программного обеспечения :retry_if блок:

Мне нужно запустить :retry_if блока на JSON сообщения расшифрованных , поскольку документ JSON может быть очень большим , если запрос выполнен успешно, и альтернатива , чтобы разобрать его во второй раз в retry_if , что кажется совершенно ненужным.

Действия по воспроизведению

<strong i="23">@_client</strong> ||= Faraday.new(url: ROOT_URL) do |f|
      f.options[:timeout] = 10
      f.headers['Content-Type'] = 'application/json'
      f.use :instrumentation, name: INSTRUMENTATION_EVENT_NAME
      f.response :json, content_type: /\bjson$/
      f.request :retry, FARADAY_RETRY_OPTIONS
end

Примечание. Если я печатаю внутри блока f.instance_variable_get :@handlers , я вижу промежуточное ПО в том порядке, в котором я его объявил.

Когда запрос не удается, и я оцениваю эти выражения в :retry Middleware пакет :retry_if блока, я получаю следующий результат:

(byebug) environment.response.to_hash.without(:url)
{:status=>405, :body=>"{\"message\": \"The method is not allowed for the requested URL.\"}\n", :response_headers=>{"date"=>"Fri, 23 Apr 2021 18:17:16 GMT", "content-type"=>"application/json", "content-length"=>"64", "connection"=>"keep-alive", "server"=>"gunicorn", "allow"=>"HEAD, OPTIONS, GET"}}

(byebug) environment.response.body
"{\"message\": \"The method is not allowed for the requested URL.\"}\n"
(byebug) environment.response.body.class
String

По сути, промежуточное программное обеспечение синтаксического анализа просто отказывается запускаться первым.

JSON правильно сформирован, а заголовок ответа Content-Type установлен правильно, поэтому я в тупике.

Мое единственное предположение - это как-то связано с #response промежуточное ПО всегда запускается до #request промежуточного ПО, но в этом случае retry являющееся #request промежуточное ПО, является чем-то вроде неправильного употребления. потому что он неявно должен быть оценен после того, как ответ будет возвращен.

Самый полезный комментарий

Привет, @mvastola , вы испытываете ожидаемое поведение!
Я знаю, что сначала трудно понять это, но, учитывая характер стека промежуточного программного обеспечения, похожего на стэк, промежуточное программное обеспечение просматривается в обратном порядке для ответов.
На нашем веб-сайте есть изображение, которое иллюстрирует это, чтобы облегчить понимание.

Значит, ты уже поступил правильно 🙌! Перемещая промежуточное ПО :json после :retry one, вы разрешаете обработку ответа этим первым, и промежуточное ПО :retry обнаружит, что тело ответа проанализировано.

Я закрываю это сейчас, но не стесняйтесь отвечать, если у вас возникнут дополнительные вопросы.

Все 4 Комментарий

Обновление: я буквально перевернул порядок двух промежуточных программ в блоке конфигурации подключения (думая, что «это не может сработать»), и теперь он работает отлично. Но оставлю это, потому что я понятия не имею, что происходит, и это все еще кажется ошибкой (или, по крайней мере, должно быть лучше задокументировано).

Привет, @mvastola , вы испытываете ожидаемое поведение!
Я знаю, что сначала трудно понять это, но, учитывая характер стека промежуточного программного обеспечения, похожего на стэк, промежуточное программное обеспечение просматривается в обратном порядке для ответов.
На нашем веб-сайте есть изображение, которое иллюстрирует это, чтобы облегчить понимание.

Значит, ты уже поступил правильно 🙌! Перемещая промежуточное ПО :json после :retry one, вы разрешаете обработку ответа этим первым, и промежуточное ПО :retry обнаружит, что тело ответа проанализировано.

Я закрываю это сейчас, но не стесняйтесь отвечать, если у вас возникнут дополнительные вопросы.

Спасибо за быстрое, доброе и подробное объяснение. Это не так уж сложно понять, но здесь это немного не интуитивно. Интересно, есть ли эффективный способ сделать это не так.

Документы

Я действительно видел документацию, которую вы связали, и это заставило меня подумать, что я знаю, что мне нужно делать. (Я видел изображение и материал о "самом внутреннем" промежуточном программном обеспечении, но на самом деле я не осознавал, что это означает изменение порядка.)

Показанное изображение является информативным в отношении внутреннего устройства промежуточного программного обеспечения, но может быть полезно дополнить его визуальным указанием того, как порядок в блоке конфигурации влияет на порядок выполнения.

Конфигурация

Помимо этого, есть множество деталей этой реализации, которые делают это не интуитивно понятным:

  • В faraday есть три разные функции для добавления промежуточного программного обеспечения, и они не взаимозаменяемы: кажется, что каждый компонент промежуточного программного обеспечения работает только с одним из них. Это создает впечатление, что существует три разных стека (или порядка) промежуточного программного обеспечения, независимых друг от друга.

  • Что делают эти три разных имени / группы промежуточного программного обеспечения, очень неясно, однако, поскольку большая часть промежуточного программного обеспечения _не_ запускается на обоих концах пути запрос-> ответ, пользователь будет склонен предположить, что задачи «запрос» всегда выполняются перед «ответом». связанные вещи.

  • Ключевое слово стойки для добавления промежуточного программного обеспечения, use , применяется (насколько я могу судить) в Фарадея только к этому типу промежуточного программного обеспечения - промежуточного программного обеспечения, которое охватывает как запрос, так и ответ.

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

Спасибо @mvastola , это бесценный отзыв 🙏!
И, честно говоря, я не в первый раз слышу об этом.

Что касается документации, я согласен, что до нас еще далеко, поэтому любой вклад в ее улучшение очень приветствуется (на самом деле, на эту тему есть ветка обсуждения совсем недавно!).

Пункты по настройке также очень верны, позвольте мне просто сказать, что путаница с методами request , response и use возникала несколько раз, до такой степени, что я на самом деле рассматривает возможность просто отказаться от них в пользу наличия use , оставив затем промежуточному программному обеспечению документировать, что и когда они будут манипулировать запросом / ответом.
Поэтому я бы посоветовал пока не настаивать на каких-либо пиарах, чтобы изменить этот API, но мы очень открыты, чтобы услышать мнение сообщества по этой теме в обсуждениях.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги