2009-07-29 2 views
6

Я разрабатываю небольшое приложение, которое отправляет XML в некоторый веб-сервис. Это делается с помощью Net :: HTTP :: Post :: Post. Однако поставщик услуг рекомендует использовать повторное подключение.Реализация стратегии повторного подключения с использованием Ruby Net

Что-то вроде: 1 запрос не -> попробуйте еще раз через 2 секунды второй запрос терпит неудачу -> Повторите попытку через 5 секунд третий запрос терпит неудачу -> Повторите попытку через 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)} 

Большое спасибо, всегда цените вашу поддержку.

Matt

ответ

15

Это один из тех редких случаев, когда Руби 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

+0

Avdi, каков хороший способ проверить это? (используя rspec или любой) – Mike

+0

Спасибо. Кстати, кажется, что 'SomeException', к сожалению, будет' StandardError', cf: http://stackoverflow.com/questions/5370697/what-s-the-best-way-to-handle-exceptions-from-nethttp. Не очень, но, по крайней мере, он ограничен областью и не проглатывается, если это непереходная, фактическая ошибка. – chesterbr

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 

To:

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

красивый драгоценный камень thx для наконечника – daniel

+0

они не равны: сначала выполняет 4 связи с задержками 0,3,5,10; второй выполняет 10 попыток с 1 секундой задержки. – hlcs

Смежные вопросы