Executa um bloco de código e o experimenta quando ocorre uma exceção. É ótimo ao trabalhar com os Serviços da Web Flakey (por exemplo).
Ele :sleep_method :matching usando :not :exception_cb :sleep :ensure :tries :on Se ocorrer uma exceção, ele voltará a tentar (n-1) vezes.
Se o número de tentativas for alcançado sem sucesso, a última exceção será aumentada.
Instale a gema:
$ gem Install Rexyable
Adicione -o ao seu GemFile:
Gem 'repetível'
Abra um URL, tente novamente duas vezes quando ocorre um OpenURI::HTTPError .
requer "abertura aberta".
xml = aberto ("http://example.com/test.xml") .readendExperimente o bloco para sempre.
# Para versões Ruby antes de 1.9.2 Uso: Símbolo Infinito em vez de Retirável.Retryable (Tentries: Float :: Infinity) Do # Código aqui
Faça alguma coisa, tente novamente quatro vezes para ArgumentError e Timeout::Error .
Remolável.Retryable (tenta: 5, on: [ArgumentError, Timeout :: Error]) fazer # Código aqui
Certifique -se de que o bloco de código seja executado, independentemente de uma exceção ter sido levantada. Não importa se o bloco sai normalmente, se tentar executar o bloco de código ou se for encerrado por uma exceção não capturada - o :ensure o bloco seja executado.
f = file.open ("testFile") garantir_cb = proc do | petiplies | coloca "Total de tentativas de repetição: #{tentativas}"
f.CloseEndRetRable.RetRyable (verifique se: garantir_cb) faça
# Process FileENDcontexts: {},
ensure: proc { },
exception_cb: proc { },
log_method: proc { },
matching: /.*/,
not: [],
on: StandardError,
sleep: 1,
sleep_method: lambda { |n| Kernel.sleep(n) },
tries: 2Remolável também pode ser configurado globalmente para alterar esses padrões:
REMYBLE.CONFIGURA 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 = 2EndPor padrão, aguardam um segundo entre as tentativas. Você pode mudar isso e até fornecer seu próprio esquema de retirada exponencial.
Remolável.Retryable (Sleep: 0) {} # Não faça uma pausa entre a TriesRetRyable.RetRyable (Sleep: 10) {} # Durma dez segundos entre a Retriesretable.Retryable (Sono: Lambda {| n | 4 ** n}) {} # Sleep 1, 4, 16, etc. cada tentativaVocê também pode tentar novamente com base na mensagem de exceção:
REMYBLE.RETRYABLE (MAIS: /Timeout /io /) Do | Betters, Exception | Levante "Oops IO Timeout!" Se fortiplas == 0END#Param de correspondência também suporta o formato da matriz: novamente: Levante "Oops IO Timeout!" Se fortiplas == 0END
Seu bloco é chamado com dois parâmetros opcionais: o número de tentativas até agora e a exceção mais recente.
REMYBLE.RETRYABLE DO | EXCEÇÃO, Exceção | coloca "Try #{Betes} falhou com a exceção: #{Exception}" se fortiplas> 0
# Código aqui Exception_CB = Proc Do | Exceção | # http://smartinez87.github.io/exception_notification
ExceptionNotifier.Notify_Exception (Exceção, Dados: {Mensagem: "It Failed"}) endretyable.Retryable (excepcion_cb: excepcion_cb)
# Código aqui # ou extraia -o para a configuração global: log_method = lambda do | tentativas, exceção | Logger.New (stdout) .Debug ("[Tente ## {EXTIDA}] Representando porque [ #{excepcion.class} - #{excepcion.message}]: #{excepcion.backtrace.first (5) .Join (' |. Levante "Oops IO Timeout!" Se Bettes == 0END #D, [2018-09-01T18: 19: 06.093811 #22535] Debug-: [Tentativa #1] Representando porque [RuntimeError-Oops IO Timeout!]: (IRB #1): 6: in. `Bloco em irb_binding '| /home/nikita/projects/retryable/lib/retryable.rb:73:in `retable '| (IRB#1): 6: em `irb_binding '| /home/nikita/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/irb/workspace.rb:85:in `avaliação '| /home/nikita/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/irb/workspace.rb:85:in `avaliar 'Se você preferir usar o madeireiro nativo do Rails:
LOG_METHOD = LAMBDA DO | EXCEÇÃO, Exceção | Rails.Logger.debug ("[Tentn ## {petrins}] Réplica porque [ #{excepcion.class} - #{excepcion.message}]: #{excepcion.backtrace.first (5) .Join ('|') }")fim Os contextos permitem extrair opções de chamadas Retryable.retryable .
REMYBLE.CONFIGURA DO | CONFIG | config.contexts [: falha_service] = {on: [FaultyServiceTimeouterror], Sleep: 10, tenta: 5
} endretherable.with_context (: falha_service) {
# Código aqui}Você também pode substituir as opções definidas em seus contextos:
#: On & Sleep definido no contexto anteriormente ainda são efetivos. # Código aqui}
Retratable.enabled? => Trueretyable.Disableretryable.enabled? => False
Não serão feitas mais tentativas se uma exceção listada em :not for levantada. Tem precedência sobre :on .
classe MyError <StandardError; endretryable.retryable (tenta: 5, on: [StandardError], não: [MyError]) Do Levante MyError "sem tentativas!" Fim
:sleep_method para usarIsso pode ser muito útil quando você está trabalhando com o celulóide, o que implementa sua própria versão do sono do método.
Remolável.Retryable (Sleep_method: Celluloid.Method (: Sleep)) Faça # Código aqui
Esta biblioteca visa apoiar e é testada nas seguintes versões 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
NOTA: Se você precisar retryable para executar no Ruby 1.8, use versões GEM antes da versão 3.0.0
Se algo não funcionar em uma dessas versões, é um bug.
Essa biblioteca pode trabalhar inadvertidamente (ou parece funcionar) em outras versões do Ruby, no entanto, o suporte só será fornecido para as versões listadas acima.
Se você deseja que esta biblioteca suportasse outra versão ou implementação do Ruby, pode ser voluntário para ser um mantenedor.