Reputation: 12923
So I have a module that is trying to make use of multiple threads, one per site. It then trying to do a request on each thread. From there I am trying to say:
Create a thread for each site, make a post request to another site, if the response.code
that comes back is a 500, wait 15 seconds and try again. Try only 5 times, upon the fifth failure - send an email
I am trying to do this in such a way that the code is easily testable with output having to validate that a thread is created. In other words, my tests only care about the response coming back from the request, I have integration tests that test the actual "wait 15 seconds ... " part.
What I have so far is:
module BlackBird
module PublishToSites
module User
def self.publish_user(params)
if Site.all != nil
threads = []
Site.all.each do |s|
threads << Thread.new do
publish(s, params)
end
end
threads.each { |t| t.join }
else
# Send Email
# - Use No Sites Template
end
end
private
def self.publish(site, params)
response = Typhoeus.post(
s.site_api_url + 'users',
:body => params.to_json,
:headers => {
"Authorization" => "Token #{s.site_api_key}",
'Content-Type' => 'application/json'
}
)
return deal_with_response(response)
end
def self.deal_with_response(response)
if response.code == 200
elsif response.code == 500
# wait and try again after 15 seconds for a total of 5 times.
# should we fail on the 5th try, use the email template: Recieved 500.
end
end
end
end
Because this is running on the JVM I will have no issue with multithreading and things should generally run faster then the MRI, speed is of an essence here.
So How do I, once I reach the response.code == 500
section, actually say, wait 15 seconds, try again for a total of 5 times?
Upvotes: 0
Views: 60
Reputation: 7166
since you do not have this code structured and the Thread.new
is not just an implementation detail you will need to pass a counter and the "full" state around to the place where you want to "sleep and retry" e.g. :
def self.publish(site, params, try = 0)
response = Typhoeus.post(
site.site_api_url + 'users',
:body => params.to_json,
:headers => {
"Authorization" => "Token #{site.site_api_key}",
'Content-Type' => 'application/json'
}
)
return deal_with_response(response, site, params, try)
end
def self.deal_with_response(response, site, params, try = 0)
if response.code == 200
elsif response.code == 500
# wait and try again after 15 seconds for a total of 5 times.
# should we fail on the 5th try, use the email template: Recieved 500.
if ( try += 1 ) < 5
sleep(15)
publish(site, params, try)
else
send_email "received response 500 for 5 times"
end
end
end
be aware since you're joining on the created threads that the requests will wait potentially ~ 5x15 seconds before returning a response ... when there are 500 failures!
Upvotes: 1