Faraday: Автоматически установить для @handler значение Faraday.default_adapter, если не указано иное.

Созданный на 22 февр. 2012  ·  35Комментарии  ·  Источник: lostisland/faraday

Обычно для наших простых скриптов мы устанавливаем Faraday.default_adapter один раз вверху, однако при работе с Github, который (без обид) любит перенаправления, мы должны использовать faraday_middleware (хорошо, не обязательно использовать), чтобы следовать перенаправлениям, что требует от нас блокирования (я предположим) Я думаю, было бы лучше, если бы Фарадей предположил, что обработчик должен быть установлен на Faraday.default_adapater, если он не установлен с использованием в блоке, это экономит некоторое кодирование и избыточный код IMO.

refactoring

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

+1 к этому. Как минимум ошибка, что адаптер не указан, а лучше просто используйте default_adapter , если ничего не было указано.

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

Не уверен в этом, но пусть откроется. Стек по умолчанию: UrlEncoded + default_adapter. Если вы определяете свой собственный стек, вы должны определить его на 100%, включая адаптер. Но это правда, что я чаще всего использую default_adapter, так что это может быть и значение по умолчанию.

Я думал о рефакторинге адаптеров Фарадея, сделав их конечными точками вместо промежуточного программного обеспечения (как в # 47). Эта функция может быть частью этого изменения.

:+1: Это укусило меня во второй раз в этом году. Можно подумать, я научусь. Было бы хорошо, если бы это было исправлено.

Компромисс: Faraday.with_default_stack() , так что мы вливаем души, просто пытаясь использовать Фарадея в первый раз, не нужно ничего знать о «стеке по умолчанию», просто чтобы иметь возможность следовать редиректам. Разумный?

@jbrains Да, я понимаю, что это неудобно для пользователя. Мы можем сделать так, чтобы возникала описательная ошибка, если вы не установили адаптер или установили его не в том месте.

Я сделал это в своем проекте:

        def faraday_with_default_adapter(base, &block)
          Faraday.new(base) { | connection |
            yield connection
            connection.adapter Faraday.default_adapter
          }
        end

Я знаю, что вы не хотите поддерживать каждую перестановку, но похоже, что почти все в конечном итоге будут это делать. :) Если бы я знал, как добавить бит UrlEncoded (я с этим еще не сталкивался), то я бы добавил его сюда.

Проверка в стиле lint с описательной ошибкой, безусловно, поможет. Спасибо. Тем не менее, небольшое покайоке помогло бы нам еще больше.

Я рассмотрю возможность отправки вам запроса на включение в будущем. А пока спасибо.

Это потребовало нескольких часов работы, когда я попытался выполнить загрузку и не указал адаптер по умолчанию (который, как я предполагал, уже установлен, поскольку он используется по умолчанию). Я продолжал отлаживать и проверять объекты ответа/запроса, и проблем не было вообще, за исключением того, что мне не хватало ужасной строки адаптера по умолчанию.

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

Спасибо!

Это укусило меня и сегодня со следующим примером:

conn = Faraday.new(url: "http://www.example.com") do |faraday|
  faraday.response :json, content_type: /\bjson$/
end

response = conn.get("stuff")

Ошибка появилась в faraday_middleware при попытке получить заголовки ответа, когда они были nil . Немного вводит в заблуждение. Было ли принято решение относительно «наилучшего способа» справиться с этим?

  • Используйте адаптер по умолчанию, если он не указан (лучший IMO)
  • Поднимите ошибку, если она не указана
  • Обновите README

Я был бы более чем счастлив представить PR

Не надо пиара. Мы постараемся решить эту проблему в следующем релизе.

Спасибо, @mislav.

Да, вчера я потратил час на погоню за этим. Приятно видеть, что исправление уже в пути. Когда ожидается следующий релиз? Последним был январь, который кажется ужасно долгим.

В четверг, 2 октября 2014 г., в 17:49, Джон Карни, [email protected]
написал:

Когда ожидается следующий релиз? Последний был в январе, кажется
ужасно долго.

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

Как насчет простой золотой середины: при попытке сделать запрос при отсутствии адаптера возникает исключение.

Или есть вариант использования для «запросов» без адаптера?

В пятницу, 3 октября 2014 г., в 14:07, Джон Бахир, [email protected]
написал:

Как насчет простой золотой середины: если сделать попытку сделать
запрос при отсутствии адаптера вызывает исключение.

Как определить, установлен ли адаптер?

Обратите внимание, что пользовательский адаптер, реализованный кем-то, не обязательно имеет
в подкласс Faraday::Adapter.

Ах я вижу. Поскольку адаптер является одноуровневым компонентом другого промежуточного программного обеспечения, а единственный API для тестирования — это стандартный стоечный API, невозможно определить, является ли промежуточное ПО адаптером http. :садтромбон:

Если это будет реализовано, изменения в # 496, вероятно, можно будет отменить (если они были объединены в первую очередь).

+1 к этому. Как минимум ошибка, что адаптер не указан, а лучше просто используйте default_adapter , если ничего не было указано.

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

Глупо, что мы вообще остались без адаптера. Ты никогда этого не хочешь...

Я просто хочу заверить всех, что мы внутри обсуждаем стратегию управления этим.
Я знаю, что это звучит как простая проверка, но, как уже объяснил @mislav , в настоящий момент у нас есть проблема, связанная со свободой людей, которые должны добавлять адаптеры в стек промежуточного программного обеспечения.
По сути, на данный момент и «адаптер» есть не что иное, как промежуточное ПО, как и любое другое, выполняющее запрос.
Теперь, когда вы определяете свой собственный стек ПО промежуточного слоя, мы теряем возможность обнаружения адаптера из других ПО промежуточного слоя, если только вы не используете метод #adapter при построении соединения. К сожалению, на данный момент его использование не является обязательным, что делает невозможным обнаружение адаптера.

Прохладный! Вот спасибо за наводку :)

14 ноября 2016 г., в 14:45, [email protected] написал:

Я просто хочу убедиться, что мы обсуждаем стратегию внутри компании.
управлять этим.
Я знаю, это звучит как простая проверка, но как
@mislav уже объяснил, что у нас есть проблема в
момент, связанный со свободой, люди должны добавлять адаптеры в
стек промежуточного программного обеспечения.
По сути, на данный момент и "адаптер" есть не что иное, как промежуточное ПО, вроде
любой другой, выполняющий запрос.
Теперь, когда вы определяете свой собственный стек ПО промежуточного слоя, мы теряем возможность
обнаружить адаптер от других промежуточных программ, если вы не используете #adapter
метод при построении соединения. К сожалению, использование его не
обязательным в данный момент, что делает невозможным обнаружение адаптера.


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub или отключите звукнить .

https://v2.developer.pagerduty.com/docs/аутентификация

Таким образом, документация PagerDuty API для ruby+faraday демонстрирует такое поведение; если вы просто используете их код, это не сработает. (Если они не исправят это, что, вероятно, они сделают теперь, когда я указал на отсутствие адаптера.)

Честно говоря, мое предложение было бы таким:

Если я вызываю «conn.get», а у conn нет адаптера, возникает исключение, сообщающее мне, что . Текущее поведение заключается в немедленном возврате, но без установки вещей в состояния, которые Фарадей описывает как результат вызова get. Так, например, «.status» по-прежнему равен нулю. Это действительно удивительное поведение! Я бы сказал, что «я ничего не могу сделать, потому что понятия не имею, что вы хотите, чтобы я сделал», вероятно, должен произвести какую-то диагностику.

Привет @seebs , я знаю, что это звучит глупо, но я объяснил, почему это не так просто сделать, как могло бы показаться в моем предыдущем комментарии:

Когда вы определяете свой собственный стек ПО промежуточного слоя, мы теряем возможность обнаружения адаптера из других ПО промежуточного слоя, если только вы не используете метод #adapter при построении соединения. К сожалению, на данный момент его использование не является обязательным, что делает невозможным обнаружение адаптера.

Я пытался проследить, что происходит, и я что-то упускаю.

Если вы сделаете очевидную вещь, которую делают многие люди, и не укажете адаптер, то при вызове get вы, в конце концов, окажетесь в build_response вack_builder, который выполняет app.call. И я... на самом деле не уверен, куда это идет, потому что я не вижу, где установлено приложение.

Итак, я думаю, что мне интересно, если вы никогда не делаете «адаптер: foo», что в конечном итоге вызовет?

Одно тривиальное решение:
def инициализировать (обработчики = [])
@handlers = обработчики
если block_given?

  • self.adapter Faraday.default_adapter
    построить (&Proc.новый)
    элсиф @handlers.пусто?

... Я думаю, это сработает (-иш)?

Кроме того, после сборки (&Proc.new) проверьте, установлен ли self.adapter.

Несмотря на то, что adapter :foo является наиболее часто используемым способом настройки адаптера, существуют и другие способы сделать это.
#adapter на самом деле просто помощник, но вы можете использовать #use , чтобы поместить адаптер в стек:

conn = Faraday.new(url: "http://www.example.com") do |faraday|
  faraday.response :logger
  faraday.use Faraday::Adapter::NetHttp
end

Так что же такое адаптер на данный момент? Не более чем промежуточное ПО, которое выполняет вызов и сохраняет результат в env . Вот почему мы не можем просто полагаться на вызываемый метод #adapter . Мы не можем полагаться на промежуточное ПО, которое работает как адаптер для наследования от Faraday::Adapter , потому что это также не является обязательным требованием.

Единственное решение — использовать версию Faraday 1.0, чтобы сделать обязательным использование метода #adapter , или предположить, что он будет использоваться, и поместить адаптер по умолчанию в стек, если метод не вызывается.

Мы все еще обсуждаем, какое из них будет лучшим решением, поскольку так или иначе люди получат неожиданные результаты после обновления.
Это то, что происходит со многими людьми, когда они впервые используют Faraday, я согласен, но определенно хуже, когда это происходит в вашей производственной системе после запуска bundle update :)

Я думаю, что я не понимаю... Если вы никогда не устанавливали адаптер, что в конечном итоге обрабатывало вызов и сохраняло результат? Я думаю, что есть вызов, который, если вы выбрали адаптер, использует метод call() адаптера. Если вы не выбрали адаптер, какой код на самом деле выполняется?

Здесь я выбрал адаптер, не используя метод #adapter .

  faraday.use Faraday::Adapter::NetHttp

Возьмите мой фрагмент из моего предыдущего комментария и попробуйте, он просто сработает.
Дело в том, что вы можете протолкнуть адаптер в стек разными способами, и как только он там окажется, он будет использован в запросе (вызов метода #call )

Извините, я, видимо, неясно выразился. Я знаю, что вы можете выбрать адаптер несколькими способами.

Но учтите распространенную ошибку новичка, когда он не выбирает адаптер, а затем вызывает conn.get(...). Что на самом деле происходит, кроме «ничего, что не имело бы никакого эффекта»?

Я пытался отследить звонки и не смог понять, что на самом деле происходит. Похоже, что Connection определила получение по умолчанию, которое вызывает run_request. Это, в свою очередь, вызывает build_request и build_response, и я думаю, что это заканчивается в build_response() вack_builder, который вызывает app.call(), и кажется, что приложение генерирует объект Response, который обрабатывает call(). Но потом я путаюсь. Я не вижу, чтобы Response даже определял метод call(), и я не могу понять, что в конечном итоге приводит к вызову метода call().

Я как бы предполагаю, что есть что- то , у чего есть метод вызова, который вызывается. Если вы выбрали адаптер, вы получите метод вызова этого адаптера. Если вы не выбрали адаптер, откуда берется фактически выполняемый метод вызова?

После настройки запроса и ответа Connection проходит через каждое промежуточное ПО и вызывает для них метод call(env) в том же порядке, в котором заполняется стек.
Он не делает никакого различия между «обычными промежуточными программами» и адаптером, он просто предполагает, что одним из промежуточных программ является адаптер. Если в стеке нет "адаптерного промежуточного ПО", будут вызываться все остальные промежуточные ПО (метод call ), но ни одно из них не сможет эффективно выполнить запрос (это роль адаптера).
Это означает, что в ответе будет отсутствовать статус, тело и все другие поля, которые заполняются «промежуточным программным обеспечением адаптера».

Понимаю, что это не очень просто, но надеюсь теперь стало понятнее 😅

Ах-ха! Вот чего я не понял. Мне не приходило в голову, что все они предоставляют функции call().

Что, если после вызова всего кода возникнет исключение, если статус не установлен? «StatusNotSetException: статус не был установлен. Скорее всего, ваше промежуточное ПО не указывает адаптер для фактического выполнения сетевой выборки».

Я бы очень хотел, чтобы это было исправлено!

Исправлено в #750 @iMacTia — вы бы закрыли это?

@olleolleolle да, хорошая мысль! Я думал, что это будет закрыто автоматически, упомянув об этом :(

Похоже, это никогда не выпускалось? Есть ли шанс увидеть минорный релиз до 1.0? :speak_no_evil:

@franzliedke , вы правы, в настоящее время это включено в версию 1.0, и я согласен, что оно было объединено довольно давно 😅.
Тем не менее, мы добились большого прогресса в направлении версии 1.0, и я бы сказал, что мы довольно близки к тому, чтобы перейти черту.
Попробуйте дать нам еще немного времени, ожидание того стоит 😃

Рад слышать!

Извините за некоторую требовательность — я знаю, насколько напряженным может быть открытый исходный код. Спасибо за отличный софт!

Совсем нет @franzliedke !
Цените толчок, мы действительно должны стремиться и выпустить v1.0 раньше, чем позже.
Посмотрите репозиторий, если вы еще этого не сделали, чтобы не пропустить запуск 👍

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