ํจ๋ฌ๋ฐ์ด ๋ฒ์ :
ํจ๋ฌ๋ฐ์ด (0.11.0)
ํจ๋ฌ๋ฐ์ด_๋ฏธ๋ค์จ์ด(0.11.0.1)
faraday_middleware-aws-signers-v4(0.1.5)
๋ฃจ๋น ๋ฒ์ :
๋ฃจ๋น 2.3.0p0 (2015-12-25 ๊ฐ์ ํ 53290) [x86_64-darwin15]
์ผ๋ถ API์ ์ก์ธ์คํ๋ ์ธํฐํ์ด์ค๊ฐ ์๊ณ get ๋ฉ์๋์ ํจ๊ป ํจ๋ฌ๋ฐ์ด ์ฐ๊ฒฐ์ ์ฌ์ฉํ๊ณ ์ฌ์๋๋ฅผ ์ค์ ํ๊ณ ๋ชจ๋ ๊ฒ์ด ์ ๋๋ก ์๋ํ๊ณ ๋ฉ์๋๋ฅผ ๊ฒ์ ๋ก ๋ณ๊ฒฝํ ๋ค์ ์ฌ์๋๊ฐ ์๋์ ๋ฉ์ท์ต๋๋ค. ๊ตฌ๊ธ๋ง์ ํด๋ณด๋ ๊ฒ์๋ฌผ ์ด ์๋๋ผ๋ ๊ฒ์ ์ดํดํ์ต๋๋ค. ์ ํฌํจ
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]
์ฐธ์กฐ: https://github.com/lostisland/faraday/pull/437/files
POST๋ฅผ ๋ค์ ์๋ํ๊ณ ์ถ์ง๋ง ๋ฌธ์ dor 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
๋ก ์ธ์คํด์คํํ ์ ์๋ proc
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ฐ๋ผ์ 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์ ๊ฒ์๋ฌผ ์ ๊ฐ๋จํ ์ถ๊ฐํ๋ฉด ์ด์ ์ฌ์๋ ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
@iMacTia ๐ ์ ๋ง ๊ฐ์ฌํฉ๋๋ค.
@yusefu ํผ๋๋ฐฑ์ ๊ฐ์ฌ๋๋ฆฌ๋ฉฐ TypeError์ ๋ํด ์ฃ์กํฉ๋๋ค.
๋ฌธ์ ๋ @connections
๊ฐ ๋ฐฐ์ด์ด ์๋๋ผ ํด์์ฌ์ผ ํ๋ค๋ ๊ฒ์
๋๋ค.
<strong i="9">@connections</strong> ||= {}
์ด์จ๋ ์ด์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ด ๊ธฐ์ฉ๋๋ค ๐!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
@yusefu ํผ๋๋ฐฑ์ ๊ฐ์ฌ๋๋ฆฌ๋ฉฐ TypeError์ ๋ํด ์ฃ์กํฉ๋๋ค.
๋ฌธ์ ๋
@connections
๊ฐ ๋ฐฐ์ด์ด ์๋๋ผ ํด์์ฌ์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.์ด์จ๋ ์ด์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ด ๊ธฐ์ฉ๋๋ค ๐!