Faraday: Как использовать повтор с методом POST

Созданный на 12 мар. 2018  ·  3Комментарии  ·  Источник: lostisland/faraday

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

  • Версия Фарадея:
    фарадей (0.11.0)
    faraday_middleware (0.11.0.1)
    faraday_middleware-aws-signers-v4 (0.1.5)

  • Рубиновая версия:
    ruby 2.3.0p0 (25 декабря 2015 г., редакция 53290) [x86_64-darwin15]

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

У меня есть интерфейс, обращающийся к некоторому API, я использовал соединение Фарадея с методом get и настроил повторную попытку, и все работало нормально, пока я не изменил свой метод на публикацию , после чего повторная попытка перестала работать. Я немного погуглил, поэтому понял, что сообщение не включены в

IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]

ссылка: https://github.com/lostisland/faraday/pull/437/files
и я должен использовать retry_if , если я хочу повторить POST, но не нашел документацию по retry_if .

Итак, мое подключение выглядит так:

    def my_connection(my_api_endpoint)
      Faraday.new(url: my_api_endpoint) do |faraday|
        faraday.request  :retry, max: 5, exceptions:
          [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed]
         faraday.response :logger
         faraday.adapter  Faraday.default_adapter
         faraday.options[:open_timeout] = 10
      end
    end

и называя это так:

  res = my_connection(my_api_endpoint).post do |req|
    req.headers['Content-Type'] = 'application/json'
    req.options.timeout = 25
    req.body = body.to_json
  end

Любая помощь будет очень кстати.

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

Спасибо за отзыв @yusefu и извините за TypeError.
Я думаю, проблема в том, что @connections должен быть хэшем, а не массивом, мой плохой!

<strong i="9">@connections</strong> ||= {}

В любом случае, рад узнать, что ваша проблема теперь решена 👍!

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

Привет @yusefu , приносим извинения за отсутствие документации, это то, что мы пытаемся решить в версии 1.0.
А пока позвольте мне помочь с вашей проблемой. По сути, retry_if — это вариант, который вы можете передать точно так же, как вы передаете max: 5, exceptions: [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed] . Единственное отличие состоит в том, что retry_if должна быть функцией (либо лямбдой, либо процедурой.
Если вы не знакомы с ними, я бы посоветовал использовать proc , который можно создать с помощью Proc.new { ... } или многострочного Proc.new do ... end .

Итак, если вы хотите использовать retry_if , ваш пример будет выглядеть примерно так:

def my_connection(my_api_endpoint)
  # This is optional, I've added the <strong i="17">@connections</strong> memoized variable to avoid
  # re-creating the connection every time. Not sure it's applicable to your case
  # but consider it as it might improve performances
  <strong i="18">@connections</strong> ||= []
  @connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
    faraday.request  :retry, max: 5, exceptions:
      [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
      retry_if: Proc.new do |env, exception|
        # your implementation goes here...
      end
     faraday.response :logger
     faraday.adapter  Faraday.default_adapter
     faraday.options[:open_timeout] = 10
  end
end

Однако, если ваша единственная цель — добавить :post в список методов повтора, вы также можете использовать опцию methods , добавленную в тот PR, который вы связали:

def my_connection(my_api_endpoint)
  # This is optional, I've added the <strong i="23">@connections</strong> memoized variable to avoid
  # re-creating the connection every time. Not sure it's applicable to your case
  # but consider it as it might improve performances
  <strong i="24">@connections</strong> ||= []
  @connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
    faraday.request  :retry, max: 5, exceptions:
      [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
      methods: Faraday::Request::Retry::IDEMPOTENT_METHODS + [:post]
     faraday.response :logger
     faraday.adapter  Faraday.default_adapter
     faraday.options[:open_timeout] = 10
  end
end

Пожалуйста, дайте мне знать, если это поможет 😄

Экземпляр соединения выдал TypeError.

expected MyAPI::BadRequest, got #<TypeError: {:req=>{}, :res=>nil, :headers=>nil, :reason_phrase=>nil}> with backtrace:

Но с простым добавлением поста в IDEMPOTENT_METHODS повторная попытка теперь возможна.
Большое спасибо @iMacTia 🙏 это сработало.

Спасибо за отзыв @yusefu и извините за TypeError.
Я думаю, проблема в том, что @connections должен быть хэшем, а не массивом, мой плохой!

<strong i="9">@connections</strong> ||= {}

В любом случае, рад узнать, что ваша проблема теперь решена 👍!

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

Смежные вопросы

luizkowalski picture luizkowalski  ·  3Комментарии

jedeleh picture jedeleh  ·  3Комментарии

mattmill30 picture mattmill30  ·  4Комментарии

QuinnWilton picture QuinnWilton  ·  4Комментарии

jordansissel picture jordansissel  ·  5Комментарии