Faraday: Cómo usar el reintento con el método POST

Creado en 12 mar. 2018  ·  3Comentarios  ·  Fuente: lostisland/faraday

Información básica

  • Versión Faraday:
    faraday (0.11.0)
    faraday_middleware (0.11.0.1)
    faraday_middleware-aws-signers-v4 (0.1.5)

  • Versión rubí:
    rubí 2.3.0p0 (2015-12-25 revisión 53290) [x86_64-darwin15]

Descripcion del problema

Tengo una interfaz que accede a alguna API, estaba usando una conexión de Faraday con el método de obtención y configurando un reintento, y todo funcionaba bien hasta que cambié mi método para publicar , luego el reintento dejó de funcionar. Busqué un poco en Google para entender que la publicación no es incluido en el

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

referencia: https://github.com/lostisland/faraday/pull/437/files
y tengo que usar retry_if si me gustaría volver a intentar el POST pero no encontré una documentación dor retry_if .

Así que mi conexión se ve así:

    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

y llamándolo de esta manera:

  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

Cualquier ayuda será muy bienvenida.

Comentario más útil

Gracias por los comentarios @yusefu y perdón por el TypeError.
Creo que el problema es que @connections debe ser un hash, no una matriz, ¡mi error!

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

De todos modos, ¡feliz de saber que tu problema ahora está resuelto 👍!

Todos 3 comentarios

Hola @yusefu , disculpas por la falta de documentación, esto es algo que estamos tratando de abordar en v1.0.
Mientras tanto, déjame ayudarte con tu problema. Básicamente, el retry_if es una opción que puede pasar exactamente como pasa max: 5, exceptions: [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed] . La única diferencia es que retry_if debe ser una función (ya sea lambda o proc.
Si no está familiarizado con ellos, le sugiero que vaya con un proc , que se puede instanciar con Proc.new { ... } o con el multilínea Proc.new do ... end .

Entonces, si desea usar retry_if su ejemplo sería algo como:

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

Sin embargo, si su único objetivo es agregar :post a la lista de métodos de reintento, también puede usar la opción methods agregada en ese PR que vinculó:

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

Por favor, avíseme si esto ayuda 😄

La instancia de conexiones dio un TypeError.

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

Pero con la simple adición de publicación a IDEMPOTENT_METHODS, ahora es posible volver a intentarlo .
Muchas gracias @iMacTia 🙏 funcionó.

Gracias por los comentarios @yusefu y perdón por el TypeError.
Creo que el problema es que @connections debe ser un hash, no una matriz, ¡mi error!

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

De todos modos, ¡feliz de saber que tu problema ahora está resuelto 👍!

¿Fue útil esta página
0 / 5 - 0 calificaciones