Implementieren von Re-connect-Strategie mit Ruby Net
-
05-07-2019 - |
Frage
Ich entwickle eine kleine Anwendung, die Beiträge XML zu einem gewissen Webservice. Dies geschieht mit Hilfe Net getan :: HTTP :: Beitrag :: Post. Allerdings empfiehlt der Service Provider eine erneute Verbindung.
So etwas wie: 1. Anforderung fehlschlägt -> versuchen Sie es erneut nach 2 Sekunden 2. Anforderung fehlschlägt -> versuchen Sie es erneut nach 5 Sekunden 3. Anforderung fehlschlägt -> versuchen Sie es erneut nach 10 Sekunden ...
Was wäre ein guter Ansatz sein, das zu tun? Einfach läuft in einer Schleife das folgende Stück Code, die Ausnahme abfangen und wieder nach einer Menge an Zeit laufen? Oder gibt es eine andere kluge Weise, das zu tun? Vielleicht sogar das Net-Paket hat in der Funktionalität einige gebaut, dass ich bin mir nicht bewusst?
url = URI.parse("http://some.host")
request = Net::HTTP::Post.new(url.path)
request.body = xml
request.content_type = "text/xml"
#run this line in a loop??
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
Vielen Dank, schätzt immer Ihre Unterstützung.
Matt
Lösung
Dies ist eine der seltenen Gelegenheiten, bei denen Rubys retry
kommt in handlichen. Etwas in diese Richtung:
retries = [3, 5, 10]
begin
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
rescue SomeException # I'm too lazy to look it up
if delay = retries.shift # will be nil if the list is empty
sleep delay
retry # backs up to just after the "begin"
else
raise # with no args re-raises original error
end
end
Andere Tipps
Ich benutze gem wiederholbar erneut versuchen können. Mit ihm aus transformierten Code:
retries = [3, 5, 10]
begin
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
rescue SomeException # I'm too lazy to look it up
if delay = retries.shift # will be nil if the list is empty
sleep delay
retry # backs up to just after the "begin"
else
raise # with no args re-raises original error
end
end
An:
retryable( :tries => 10, :on => [SomeException] ) do
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
end