ファラデーバージョン:
ファラデー(0.11.0)
faraday_middleware(0.11.0.1)
faraday_middleware-aws-signers-v4(0.1.5)
Rubyバージョン:
ruby 2.3.0p0(2015-12-25リビジョン53290)[x86_64-darwin15]
いくつかのAPIにアクセスするインターフェースがあり、 getメソッドでFaraday接続を使用し、再試行を設定していました。メソッドを投稿に変更するまですべてが正常に機能し、再試行が機能しなくなりました。少しググったので、投稿がそうではないことがわかりました。に含まれています
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]
参照: https ://github.com/lostisland/faraday/pull/437/files
POSTを再試行したいのに、 retry_ifのドキュメントが見つからなかった場合は、 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 、ドキュメントが不足していることをお詫びします。これはv1.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を追加することが唯一の目的である場合は、リンクしたPRに追加されたmethods
オプションを使用することもできます。
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にpostを追加するだけで、再試行が可能になりました。
どうもありがとう@iMacTia🙏それはうまくいきました。
フィードバック@yusefuをありがとう、TypeErrorをお詫びします。
問題は、 @connections
が配列ではなくハッシュであるべきだということだと思います、私の悪いことです!
<strong i="9">@connections</strong> ||= {}
とにかく、あなたの問題が解決されたことを嬉しく思います👍!
最も参考になるコメント
フィードバック@yusefuをありがとう、TypeErrorをお詫びします。
問題は、
@connections
が配列ではなくハッシュであるべきだということだと思います、私の悪いことです!とにかく、あなたの問題が解決されたことを嬉しく思います👍!