I've been struggling with Faraday and my Ruby on Rails app. An API controller in Rails creates a Model instance and sends this data serialized in JSON to an external app that will process the data and send a response with float
number inside its response within a few seconds of the request.
However, my app sometimes sends 50 individual requests and the external app may return a 502
error string as a response (please notice not an actual 502 HTTP error!!!). I tried throttling my Faraday calls, but that made the external app go berserk, so now I'm trying to figure out how to re-submit a request if the response throws out this 502
string. I haven't figured out how to write a Middleware for this, but it has not been necessary for now.
Is there a way I can tell my method to resubmit the request to the external app if it receives a certain response inside its body?
Here is my code (this method gets triggered for every request):
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
Thanks, your help is very appreciated!
You can try the code below
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
you can check out the documentation for additional information.
you can add
builder.response :raise_error
to your connection builder to automatically have Faraday raise ClientError
if the request is not successful (based on the response code, eg on 4xx/5xx codes).
You also have to add Faraday::Error
to your exceptions array in the retry
config
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.