2009-07-29 9 views
6

Zajmuję się tworzeniem małej aplikacji, która umieszcza kod XML w niektórych usługach sieciowych. Odbywa się to za pomocą Net :: HTTP :: Post :: Post. Usługodawca zaleca jednak ponowne podłączenie.Implementacja strategii Re-connect przy użyciu sieci Ruby

Coś jak: 1 wniosek nie powiedzie -> spróbować ponownie po 2 sekundach 2-cia żądanie nie powiedzie -> spróbować ponownie po 5 sekundach 3-cie żądanie nie powiedzie -> spróbować ponownie po 10 sekundach ...

Co by być dobrym podejściem do tego? Po prostu uruchamiając poniższy fragment kodu w pętli, przechwytując wyjątek i uruchamiając go ponownie po pewnym czasie? Czy jest jakiś inny sprytny sposób na zrobienie tego? Może pakiet Net ma nawet wbudowaną funkcjonalność, o której nie wiem?

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)} 

Dziękuję bardzo, zawsze dziękuję za wsparcie.

Matt

Odpowiedz

15

Jest to jeden z tych rzadkich okazjach, kiedy Ruby retry przydaje. Coś wzdłuż tych linii:

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 
+0

Doskonałe. Dzięki! – Matt

+0

Avdi, jaki jest dobry sposób na sprawdzenie tego? (używając rspec lub jakiegokolwiek) – Mike

+0

Dzięki. Wydaje się, że 'SomeException' musi, niestety, być' StandardError', cf: http://stackoverflow.com/questions/5370697/what-s-the-best-way-to-handle-exceptions-from-nethttp. Nie wspaniale, ale przynajmniej ma zasięg do linii i nie jest połknięty, jeśli jest to przejściowy, rzeczywisty błąd. – chesterbr

2

Używam klej retryable do ponowienia. Dzięki niemu Kod przekształcona z:

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 

Do:

retryable(:tries => 10, :on => [SomeException]) do 
    response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)} 
end 
+1

fajny klejnot thx za cynk – daniel

+0

nie są równe: pierwszy robi 4 krawaty z opóźnieniami 0,3,5,10; drugi robi 10 prób z 1 sekundowym opóźnieniem. – hlcs