2009-07-29 80 views
6

我正在開發一個將XML發佈到某個webservice的小應用程序。 這是使用Net :: HTTP :: Post :: Post完成的。但是,服務提供商建議使用重新連接。使用Ruby Net實現重新連接策略

喜歡的東西: 1請求失敗 - >5秒 第三請求失敗後重試 - - >2秒 第二次請求失敗後重試>嘗試10秒 後再次...

會是什麼做一個好的方法呢?只需在循環中運行以下代碼片段,捕獲異常並在一段時間後再次運行它?或者有沒有其他聰明的方法可以做到這一點?也許Net包甚至有一些我不知道的內置功能?

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

非常感謝,感謝您的支持。

馬特

回答

15

這是罕見的場合之一Ruby的retry就派上用場了。沿着這些線:

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

優秀。謝謝! – Matt 2009-07-30 06:33:33

+0

Avdi,最新的測試方法是什麼? (使用rspec或任何) – Mike 2015-03-19 16:51:17

+0

謝謝。順便說一句,似乎'SomeException'必須,不幸的是'StandardError',cf:http://stackoverflow.com/questions/5370697/what-s-the-best-way-to-handle-exceptions-from-nethttp。不是很好,但至少它被限定在一條線上,如果它是非瞬態的,實際的錯誤不會被吞噬。 – chesterbr 2016-03-26 04:10:26

2

我使用寶石retryable重試。 有了它的代碼轉化而來:

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 

要:

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

不錯的寶石thx的提示 – daniel 2014-08-05 21:30:24

+0

他們是不相等的:首先是做4延遲0,3,5,10;第二是延遲1秒,做10次嘗試。 – hlcs 2015-10-21 12:12:45