Запускает кодовый блок и перезагружает его, когда происходит исключение. Это здорово при работе с Flakey Webservices (например,).
Он настроен с использованием нескольких необязательных параметров :tries
:on
, :sleep
, :matching
, :ensure
,: :exception_cb
, :not
, :sleep_method
и запускает пропущенный блок. Если произойдет исключение, оно повторно (N-1) раз.
Если количество повторений будет достигнуто без успеха, последнее исключение будет поднято.
Установите драгоценный камень:
$ gem install Repryable
Добавьте его в свой Gemfile:
драгоценный камень
Откройте URL, повторите два раза, когда происходит OpenURI::HTTPError
.
Требуется «open-uri» stryable.retryable (попытки: 3, ON: openuri :: httperror) xml = open ("http://example.com/test.xml") .Readend
Попробуйте блок навсегда.
# Для версий Ruby до 1.9.2 Использование: Infinite Symbol вместо этого Retryable (попытки: float :: Infinity) Do # Code TreeEnd
Сделайте что -нибудь, повторите до четырех раз для ArgumentError
или Timeout::Error
Exceptions.
Stryable.retryable (попытки: 5, ON: [ArgentEerror, Timeout :: ошибка]) # Code TreeEnd
Убедитесь, что блок кода выполняется, независимо от того, поднято ли исключение. Не имеет значения, если блок выходит нормально, если он возвращается, чтобы выполнить блок кода, или если он прекращен исключением, - :ensure
что Block будет запустить.
f = file.open ("testfile") убедитесь_CB = proc do | retries | «Постановляет" Total попытки повторения: #{Retries} " f.closeendretryable.retryable (убедитесь: убедитесь, что_CB) Do # Процесс Fileend
contexts: {}, ensure: proc { }, exception_cb: proc { }, log_method: proc { }, matching: /.*/, not: [], on: StandardError, sleep: 1, sleep_method: lambda { |n| Kernel.sleep(n) }, tries: 2
Repryable также может быть настроен по всему миру, чтобы изменить эти значения по умолчанию:
Stryable.configure do | config | config.contexts = {} config.ensure = proc {} config.exception_cb = proc {} config.log_method = proc {} config.matching = /.*/ config.not = [] config.on = standarderror config.sleep = 1 config.sleep_method = lambda {| n | Kernel.sleep (n)} config.tries = 2end
По умолчанию, повторяющееся ожидает одну секунду между повторными поисками. Вы можете изменить это и даже предоставить свою собственную экспоненциальную схему отступления.
Retryable.retryable (Sleep: 0) {} # вообще не паузу между reriesretryable.retryable (Sleep: 10) {} # Sleep десять секунд между reseretryable.retryable (Sleep: лямбда {| n | 4 ** n}) {} # Sleep 1, 4, 16 и т. Д. Каждый попытка
Вы также можете повторно повторно на основе сообщения исключения:
Stryable.retryable (matching: /io timeout /) do | retries, исключение | Поднимите "упс io Timeout!" Если RETRIES == 0END#Сопоставление параметров поддерживает формат массива: stryable.retryable (Сопоставление: [/io Timeout/, "io tymeout"]) do | retries, исключение | Поднимите "упс io Timeout!" Если повторно
Ваш блок вызывается с двумя дополнительными параметрами: количество попыток до сих пор и самое последнее исключение.
Retryable.retryable do | Refries, Exception | ставит "try #{retries} с исключением с исключением: #{Exception}" If Repries> 0 # Code TreeEnd
exception_cb = proc do | Exception | # http://smartinez87.github.io/exception_notification ExceptionNotifier.notify_exception (Exception, Data: {Message: "Это не удалось"}) endretryable.retryable (exception_cb: exception_cb) do # Code TreeEnd
# или извлечь его в глобальную конфигурацию вместо: log_method = lambda do | retries, исключение | Logger.new (stdout) .debug ("[попытка ## {retries}] повторение, потому что [ #{exception.class} - #{exception.message}]: #{exception.backtrace.first (5) .join (' | Поднимите "упс io Timeout!" Если Refries == 0end #D, [2018-09-01t18: 19: 06.093811 #22535] отладка-: [Попытка № 1] Повторная попытка, потому что [RuntimeError-OOPS IO Timeout!]: (IRB #1): 6: в `block in irb_binding '| /home/nikita/projects/retryable/lib/retryable.rb:73:in `stryable '| (IRB#1): 6: в `rb_binding '| /home/nikita/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/irb/workspace.rb:85:in `eval '| /home/nikita/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/irb/workspace.rb:85:IN `rewation '
Если вы предпочитаете использовать нативный журнал Rails:
log_method = lambda do | Refries, Exception | Railss.logger.debug ("[попытка ## {retries}] повторно, потому что [ #{exception.class} - #{exception.message}]: #{exception.backtrace.first (5) .join ('|') }")конец
Контексты позволяют вам извлечь общие Retryable.retryable
возможности для целей повторного использования или читабельности.
Stryable.configure do | config | config.contexts [: faulty_service] = {on: [faultyServiceTimeouterror], Sleep: 10, попытки: 5 } endretryable.with_context (: faulty_service) { # код здесь}
Вы также можете переопределить параметры, определенные в ваших контекстах:
#: On & Sleep, определенные в контексте ранее, по -прежнему Effectiveretryable.with_context (: faulty_service, попытки: 999) { # код здесь}
Retryable.Enabled?
Больше никаких попыток не будет сделано, если исключение перечислено в :not
поднято. Имеет приоритет над :on
.
класс Myerror <StandardError; endretryable.retryable (попытки: 5, on: [StandardError], не: [myerror]) Поднимите MyError "No Repries!"
:sleep_method
для использованияЭто может быть очень полезно, когда вы работаете с целлулоидом, которая реализует свою собственную версию метода Sleep.
Stryable.retryable (sleep_method: celluloid.method (: sleep)) do # Code TreeEnd
Эта библиотека направлена на поддержку и проверяется на следующих версиях Ruby:
Ruby 3.3
Ruby 3.2
Ruby 3.1
Ruby 3.0
Ruby 2.7
Ruby 2.6
Ruby 2.5
Ruby 2.4
Ruby 2.3
Ruby 2.2
Ruby 2.1
Ruby 2.0
Примечание. Если вам нужно retryable
, чтобы работать на Ruby 1.8 Используйте версии GEM до 3.0.0
Если что -то не работает на одной из этих версий, это ошибка.
Эта библиотека может непреднамеренно работать (или, кажется, работает) над другими версиями Ruby, однако поддержка будет предоставлена только для версий, перечисленных выше.
Если вы хотите, чтобы эта библиотека поддержала другую версию или реализацию Ruby, вы можете быть добровольным, чтобы стать сопровождающим.