Exécute un bloc de code et le réchauffe lorsqu'une exception se produit. C'est génial lorsque vous travaillez avec Flakey Webservices (par exemple).
Il est configuré à l'aide de plusieurs paramètres facultatifs :tries , :on , :sleep , :matching , :ensure , :exception_cb , :not , :sleep_method et exécute le bloc passé. Si une exception se produit, elle réessayera (n-1) fois.
Si le nombre de tentatives est atteinte sans succès, la dernière exception sera soulevée.
Installez la gemme:
$ install install trichable
Ajoutez-le à votre gemfile:
gemme `` réimprimé ''
Ouvrez une URL, réessayez jusqu'à deux fois lorsqu'un OpenURI::HTTPError se produit.
exiger "Open-Uri" Repriyable.retryable (essais: 3, ON: OpenUri :: httperror)
xml = open ("http://example.com/test.xml") .readendEssayez le bloc pour toujours.
# Pour les versions rubis avant 1.9.2 Utiliser: symbole infini à la place rétractable. # Code ici
Faites quelque chose, réessayez jusqu'à quatre fois pour ArgumentError ou Timeout::Error Exceptions.
Repriyable.retryable (essais: 5, sur: [ArgumentError, Timeout :: Error]) faire # Code ici
Assurez-vous que le bloc de code est exécuté, que ce soit une exception. Peu importe si le bloc sort normalement, s'il réchauffe pour exécuter le bloc de code, ou s'il est terminé par une exception non apprise - le bloc :ensure -t-il.
f = file.open ("testfile") assure_cb = proc do | Retries | Mette "Total Rentry Tuts: # {Retries}"
f.closeEndRetryable.retryable (assurer: assure_cb) faire
# Processus Fileendcontexts: {},
ensure: proc { },
exception_cb: proc { },
log_method: proc { },
matching: /.*/,
not: [],
on: StandardError,
sleep: 1,
sleep_method: lambda { |n| Kernel.sleep(n) },
tries: 2Repriviable pourrait également être configuré globalement pour modifier ces valeurs par défaut:
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 = 2endPar défaut, RETNIable attend une seconde entre les tentatives. Vous pouvez modifier cela et même fournir votre propre schéma de backoff exponentiel.
Repriyable.retryable (Sleep: 0) {} # ne casse pas du tout entre RetrieSretryable.retryable (Sleep: 10) {} # Sleep dix secondes entre RetrieSretryable.retryable (Sleep: Lambda {| n | 4 ** n}) {} # Sleep 1, 4, 16, etc. Chaque essaiVous pouvez également réessayer en fonction du message d'exception:
Retryable.retryable (Matching: / io timeout /) do | Retries, exception | Richer "Oups Io Timeout!" Si RETRES == 0end # correspondant Param prend également en charge le format de tableau: Retrichable.retryable (correspondance: [/ io timeout /, "io Tymeout"]) do | Retries, exception | Richer "Oups Io Timeout!" Si les teint == 0end
Votre bloc est appelé avec deux paramètres facultatifs: le nombre d'essais jusqu'à présent et l'exception la plus récente.
Repriyable.retryable do | Retries, exception | met "Try # {Retries} a échoué avec exception: # {exception}" If Retries> 0
# code ici exception_cb = proc do | Exception | # http://smartinez87.github.io/exception_notification
ExceptionNotifier.Notify_Exception (exception, données: {message: "il a échoué"}) endRetryable.retryable (exception_cb: exception_cb)
# Code ici # ou l'extraire à la configuration globale à la place: log_method = lambda do | Retries, exception | Logger.New (stdout) .debug ("[tentative ## {Retries}] réessayant car [# {exception.class} - # {exception.message}]: # {exception.backTrace.First (5) .join ('' | ')} ") endRetryable.retryable (log_method: log_method, correspondant: / io timeout /) do | Retries, exception | Richer "Oups Io Timeout!" Si RETRES == 0end # D, [2018-09-01T18: 19: 06.093811 # 22535] Debug -: [Tentative # 1] Réessayant parce que [RuntimeError - Oops io Timeout!]: (IRB # 1): 6: dans `Block in IRB_BINDING '| /home/nikita/projects/retryable/lib/retryable.rb:73:in `Retryable '| (IRB # 1): 6: dans `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 vous préférez utiliser l'enregistreur natif de Rails:
log_method = lambda do | Retries, exception | Rails.logger.debug ("[tentative ## {retrries}] réessayant car [# {exception.class} - # {exception.message}]: # {exception.backtrace.first (5) .join ('|') }")fin Les contextes vous permettent d'extraire des options d'appel Retryable.retryable communes. Réutilisables à des fins de réutilisation ou de lisibilité.
Retryable.configure do | config | config.Contexts [: défectueux_service] = {on: [défectueux-desservitimeouterror], sommeil: 10, essais: 5
} endretryable.with_context (: défectueux_service) {
# code ici}Vous pouvez également remplacer les options définies dans vos contextes:
#: On & Sleep défini dans le contexte précédemment sont toujours efficaces.with_context (: défectueux_service, essais: 999) {
# code ici}Retringable.enabled? => Truetryable.disableRetryable.enabled? => False
Plus d'essais ne seront faits si une exception répertoriée dans :not est soulevée. Privit :on .
classe MyError <standarderror; EndRetryable.retryable (essais: 5, sur: [StandardError], non: [Myerror]) Richer MyError "Non Retries!"
:sleep_method à utiliserCela peut être très utile lorsque vous travaillez avec celluloïd qui implémente sa propre version du sommeil de la méthode.
Retrichable.retryable (sleep_method: Celluloïd.Method (: Sleep)) # Code ici
Cette bibliothèque vise à soutenir et est testée par rapport aux versions Ruby suivantes:
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
Remarque: si vous avez besoin de retryable la course sur Ruby 1.8 Utilisez les versions GEM avant la version 3.0.0
Si quelque chose ne fonctionne pas sur l'une de ces versions, c'est un bug.
Cette bibliothèque peut fonctionner par inadvertance (ou semble fonctionner) sur d'autres versions Ruby, mais la prise en charge ne sera fournie que pour les versions énumérées ci-dessus.
Si vous souhaitez que cette bibliothèque prenne en charge une autre version ou implémentation Ruby, vous pouvez vous porter volontaire pour être un responsable.