Ejecuta un bloque de código y lo repleta cuando ocurre una excepción. Es genial cuando se trabaja con Webservices de Flakey (por ejemplo).
Está configurado utilizando varios parámetros opcionales :tries
, :on
, :sleep
, :matching
, :ensure
, :exception_cb
, :not
, :sleep_method
y ejecuta el bloque pasado. Si se produce una excepción, volverá a intentarlo por (N-1).
Si se alcanza el número de reintentos sin éxito, se planteará la última excepción.
Instale la gema:
$ gema instalación de Vithermable
Agrégalo a su archivo gem:
gema 'Reletronable'
Abra una URL, vuelva a intentar dos veces cuando se produce un OpenURI::HTTPError
.
requiere "Open-Uri" Retryable.cretryable (intenta: 3, en: OpenUri :: httperror) do xml = open ("http://example.com/test.xml") .Readend
Prueba el bloque para siempre.
# Para versiones de Ruby antes de 1.9.2 Use: símbolo infinito en su lugar de retryable.cretryable (intenta: float :: infinito) # código presente
Haga algo, vuelva a intentar hasta cuatro veces por ArgumentError
o Timeout::Error
.
Retryable.cretryable (intenta: 5, en: [argumenterRor, timeout :: error]) hacer # código presente
Asegúrese de que se ejecute el bloque de código, independientemente de si se planteó una excepción. No importa si el bloque sale normalmente, si se reemplaza para ejecutar el bloque del código, o si es terminado por una excepción no captura, el :ensure
el bloque se ejecute.
f = file.open ("testFile") AGRESA_CB = PROC DO | reintentos | pone "intentos totales de reintento: #{reintings}" F.CloseEdrryable.cretryable (Asegúrese: AGUARIO_CB) hacer # Procesar 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
Vuelto al reintento también podría configurarse a nivel mundial para cambiar esos valores predeterminados:
Retryable.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
Por defecto, el retráfico espera un segundo entre reintentos. Puede cambiar esto e incluso proporcionar su propio esquema exponencial de retroceso.
Reintyable.rcryable (sleep: 0) {} # No se detenga entre reintrescredryable.rcryable (sleep: 10) {} # duerme diez segundos entre reintrescredryable.cretryable (sleep: lambda {| n | 4 ** n}) {} # Sleep 1, 4, 16, etc. Cada prueba
También puede volver a intentarlo en función del mensaje de excepción:
Retryable.rcryable (coincidencia: /io timeout /) do | reintentos, excepción | Levante "¡Uy io, tiempo de espera!" si reinties == 0end#parámetro coincidente también admite formato de matriz: retryable.rcryable (coincidente: [/io timeout/, "io tymeut"]) do | reintys, excepción | Levante "¡Uy io, tiempo de espera!" Si reintenta == 0end
Su bloque se llama con dos parámetros opcionales: el número de intentos hasta ahora y la excepción más reciente.
Redriendable.retryable do | reintentos, excepción | pone "try #{reintys} falló con excepción: #{excepción}" si reintentos> 0 # código presente
excepcion_cb = proc do | excepción | # http://smartinez87.github.io/exception_notificación ExceptionNotifier.Notify_Exception (Exception, Data: {Mensaje: "Falló"}) Endretryable.cretryable (excepcion_cb: excepción_cb) do # código presente
# o extraerlo a la configuración global en su lugar: log_method = lambda do | reintentos, excepción | Logger.new (stdout) .debug ("[intento ## {reinties}] Vitando porque [ #{excepcion.class} - #{excepcion.message}]: #{excepcion.backtrace.first (5) .join (' | '')} ") Endretryable.cretryable (log_method: log_method, coincidente: /io timeout /) do | reintentos, excepción | Levante "¡Uy io, tiempo de espera!" if reinties == 0end #D, [2018-09-01T18: 19: 06.093811 #22535] Debug-: [Intento #1] Vuelva `Bloque en IRB_Binding '| /home/nikita/projects/cretryable/lib/cretryable.rb:73:in `retryable '| (IRB#1): 6: En `irb_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 'Evaluate'
Si prefiere usar el registrador nativo de Rails:
log_method = lambda do | reintentos, excepción | Rails.logger.debug ("[intento ## {reintis}] Vitando porque [ #{excepcion.class} - #{excepcion.message}]: #{excepcion.backtrace.first (5) .Join ('|') }")fin
Los contextos le permiten extraer Retryable.retryable
común. Opciones de llamadas retratables para fines de reutilización o legibilidad.
Retryable.configure do | config | config.contexts [: fally_service] = {on: [fauthyServiceTimeouterror], dormir: 10, intenta: 5 } endretryable.with_context (: fally_service) { # código aquí}
También puede anular las opciones definidas en sus contextos:
#: On & Sleep definido en el contexto antes todavía son efectivos. # código aquí}
Retryable.enabled? => TrUeretryable.disableeretryable.enabled? => False
No se realizarán más intentos si se enumera una excepción en :not
se plantea. Tiene prioridad sobre :on
.
Clase MyError <StandardError; endretryable.rcryable (intenta: 5, en: [StandardError], no: [myError]) hacer Levanta myerror "¡Sin reintentos!" Fin
:sleep_method
para usarEsto puede ser muy útil cuando trabaja con celuloide que implementa su propia versión del método de sueño.
Redriendable.rcryable (sleep_method: celuloide.method (: sleep)) do # código presente
Esta biblioteca tiene como objetivo admitir y se prueba con las siguientes versiones de 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: Si necesita retryable
para ejecutar en Ruby 1.8, use versiones GEM antes de la versión 3.0.0
Si algo no funciona en una de estas versiones, es un error.
Esta biblioteca puede funcionar inadvertidamente (o parecer funcionar) en otras versiones de Ruby, sin embargo, solo se proporcionará soporte para las versiones mencionadas anteriormente.
Si desea que esta biblioteca admite otra versión o implementación de Ruby, puede ser voluntario para ser un mantenedor.