2011-01-23 21 views
11

Trong cuốn sách khiêm tốn của Ruby, một ví dụ của việc sử dụng Rescue và thử lại được cung cấp gửi tiêu đề HTTP đến một máy chủ bằng cách sử dụng đoạn mã sau:Làm cách nào để hạn chế thử lại và cứu hộ trong ví dụ Ruby này?

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

Để hạn chế một vòng lặp vô hạn trong trường hợp nó không giải quyết được, tôi sẽ phải chèn mã nào để giới hạn số lần thử lại để nói 5 lần? nó sẽ là một cái gì đó như:

5.times { retry } 

Trả lời

13

Bạn chỉ có thể viết một 5.times cộng với một break trên thành công bên trong vòng lặp, hoặc trừu tượng mô hình để giữ logic tách biệt khỏi vòng lặp. Ý tưởng:

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

Chưa hoàn toàn, nhưng đoạn trích đó dường như đủ đơn giản. Cảm ơn. – Simpleton

+0

Cảm ơn. Lý do chính của tôi để hỏi là chỉ để hiểu làm thế nào, không có một ứng dụng thực tế cho đoạn mã này được nêu ra. – Simpleton

+3

Tôi biết đây là câu trả lời cũ, nhưng [đá quý có thể truy xuất] (https://github.com/kamui/retriable) về cơ bản điều này chính xác. – ZombieDev

3

Bạn có thể thiết lập một biến để 0 và tăng nó mỗi khi bạn thử lại, cho đến tối đa đạt được, như thế này:

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

Ngoài ra bạn có thể thử nó cho mình với điều này:

def make_request 
    raise ProtocolError 
rescue ProtocolError 
    try_to_find_how_to_limit_it 
end 
+0

Cảm ơn vì điều này. – Simpleton

+2

Tôi nghĩ rằng giới hạn này nên được giới hạn || = 0, nếu không nó được thiết lập lại 0 mọi lúc. – Vincent

1

Tôi đã sử dụng chức năng này để chạy và thử lại một số lần giới hạn với thời gian trễ liên tục. Nó chỉ ra các đối số tries chỉ đơn giản có thể được tăng cường trong cơ thể chức năng và được thông qua khi retry được gọi.

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 
Các vấn đề liên quan