我一直在与法拉第和我的Ruby on Rails应用程序挣扎。 Rails中的API控制器创建一个Model实例,并将以JSON序列化的数据发送到外部应用程序,该应用程序将在请求的几秒钟内处理数据并在其响应中发送带有float
数字的响应。
但是,我的应用程序有时会发送50个单独的请求,外部应用程序可能会返回502
错误字符串作为响应(请注意不是实际的502 HTTP错误!!!)。我尝试限制我的法拉第呼叫,但这使得外部应用程序变得狂暴,所以现在我试图弄清楚如果响应抛出这个502
字符串,如何重新提交请求。我还没弄清楚如何为此编写一个中间件,但现在还没有必要。
我是否有办法告诉我的方法如果在其内部收到某个响应,请将该请求重新提交给外部应用程序?
这是我的代码(每个请求都会触发此方法):
def create
cl = Model.where(
attr1_id: params[:attr1_id],
attr2_id: params[:attr2_id]
).first_or_initialize(params)
cl.update(params)
# Send new Model data (in JSON) in a request to external app
cl_r = cl[:attr1_id]
r = Some_model.find_by(id: cl_r)
request = { :cl => cl, :r => r }
# Send the request
response = @conn.post do |req|
req.url '/ml'
req.headers['Content-Type'] = 'application/json'
req.headers['password'] = 'password'
req.body = request.to_json
end
# Get the response
response_json = response.body
response_json = response_json.gsub(/\s+/m, ' ').strip.split(" ")[1]
# If the response (which takes a few seconds) returns a float inside its response body
cl.update_attributes(response_attribute: response_json)
# Else
# Send the request that returned a 502 string inside the body to the external app again
# End
respond_with cl
end
谢谢,非常感谢您的帮助!
答案 0 :(得分:2)
您可以尝试以下代码
Faraday.new(your @conn params here if any) do |conn|
conn.request :retry, max: 2, interval: 0.05,
interval_randomness: 0.5, backoff_factor: 2,
exceptions: [CustomException, 'Timeout::Error']
response = conn.post do |req|
req.url '/ml'
req.headers['Content-Type'] = 'application/json'
req.headers['password'] = 'password'
req.body = request.to_json
end
raise CustomException if response.status == 502
...
end
您可以查看documentation以获取更多信息。
答案 1 :(得分:0)
您可以添加
builder.response :raise_error
如果请求失败(根据响应代码,例如4xx / 5xx代码),则向您的连接构建器自动发送法拉第ClientError
。
您还必须将Faraday::Error
添加到retry
配置中的例外数组中