2011-01-23 24 views
11

在Ruby中,使用救援和重試的一個例子的不起眼書提供了一種使用以下代碼發送HTTP標頭到服務器的:如何在這個Ruby示例中限制重試和救援?

def make_request 
    if (@http11) 
    self.send('HTTP/1.1') 
    else 
    self.send('HTTP/1.0') 
    end 
rescue ProtocolError 
    @http11 = false 
    retry 
end 

爲了限制的情況下,一個無限循環它不能解決,我必須插入什麼代碼才能重試5次?難道是這樣的:

5.times { retry } 

回答

13

你可以只寫一個5.times加上成功break內循環,或抽象的圖案,以保持邏輯從循環分開。一個想法:

module Kernel 
    def with_rescue(exceptions, retries: 5) 
    try = 0 
    begin 
     yield try 
    rescue *exceptions => exc 
     try += 1 
     try <= retries ? retry : raise 
    end 
    end 
end 

with_rescue([ProtocolError], retries: 5) do |try| 
    protocol = (try == 0) ? 'HTTP/1.1' : 'HTTP/1.0' 
    send(protocol) 
end 
3

你可以一個變量設置爲0,並且每次重試的時間增加了,達到你的最高直到,像這樣:

def make_request 
    limiter = 0 
    ... 
rescue ProtocolError 
    @http11 = false 
    if limiter < MAXIMUM 
    retry 
    end 
end 

此外,你可以自己嘗試一下與此:

def make_request 
    raise ProtocolError 
rescue ProtocolError 
    try_to_find_how_to_limit_it 
end 
+0

感謝您的支持。 – Simpleton 2011-01-23 14:37:14

+2

我認爲這個限制器應該是限制器|| = 0,否則它每次都被重置爲0。 – Vincent 2017-04-04 19:03:49

1

我用這個函數運行並重試一個有限次數的命令,間歇性的延遲。事實證明tries參數可以簡單地在函數體中增加,並在調用retry時傳遞。

def run_and_retry_on_exception(cmd, tries: 0, max_tries: 3, delay: 10) 
    tries += 1 
    run_or_raise(cmd) 
rescue SomeException => exception 
    report_exception(exception, cmd: cmd) 
    unless tries >= max_tries 
    sleep delay 
    retry 
    end 
end