feat(client): toute la politique de retry réglable via retry_options: - #17
Open
arsenik-dtheo[bot] wants to merge 2 commits into
Open
arsenik-dtheo[bot] wants to merge 2 commits into
arsenik-dtheo[bot] wants to merge 2 commits into
Conversation
retry_options: sur Client.new (et Jev.new) : défauts 2/0,5/8,0 pour clés absentes, valeurs nil et retry_options: nil ; validation stricte (clé inconnue ou valeur invalide -> ArgumentError nommant la clé) ; options normalisées exposées et figées, mutation du Hash passé sans effet ; max_retries: 0 = tentative unique ; base_delay/max_delay observables via les délais demandés ; héritage Jev.
Client.new (et Jev.new, qui hérite) acceptent un unique argument retry_options: (Hash) : max_retries / base_delay / max_delay, défauts 2 / 0,5 / 8,0 pour clé absente ou nil, et retry_options: nil pour tous les défauts. Validation stricte à la construction (ArgumentError nommant la clé sur clé inconnue ou valeur invalide : numériques non négatifs, max_retries entier). Le Hash normalisé est dupliqué et figé, exposé sur le client ; muter le Hash passé n'a plus d'effet. La boucle retentative et le backoff lisent la politique configurée ; la signature de evaluate ne change pas.
arsenik-dtheo
Bot
force-pushed
the
epic-6/04-retry-options
branch
from
September 21, 2026 06:12
c7e7464 to
d28f6c2
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #11
Partie de l'épic #6
🔍 Ce que fait cette PR
Toute la politique de retentative devient réglable via un unique argument
retry_options:(Hash) surClient.new, hérité parTypesafe::JevviaJev.new(retry_options:)— la signature deevaluatene change pas. Clés acceptées :max_retries,base_delay,max_delay; clés absentes ou valeursnil→ défauts (2 / 0,5 / 8,0) ;retry_options: nil→ tous les défauts. Validation stricte à la construction :ArgumentErrornommant la clé en cause sur toute clé inconnue (y compris les clés String — lecture stricte de « toute clé inconnue »),max_retriesnon entier ou négatif, délais négatifs ou non numériques,retry_optionsnon-Hash. Le Hash normalisé est dupliqué, figé (retry_optionsfrozen, client frozen) : muter le Hash passé après construction n'a plus d'effet. Les délais sont normalisés enFloat.retry_options: { max_retries: 0 }redonne le comportement d'une tentative unique (HTTP et réseau).✅ Critères couverts
Client.new(api_key:, retry_options: { max_retries: 0 })n'effectue qu'une seule tentative → tests HTTP (529) et réseau (Errno::ECONNREFUSED) :have_been_requested.once, aucun sleep, erreur levéebase_delayetmax_delayresserrent ou relâchent le backoff, observables via les délais demandés → base 1,0 → [0,5 ; 1,0] ; base 0,1 → [0,05 ; 0,1] ; plafond : base 4,0 + max_delay 0,5 → les 2 sleeps ∈ [0,25 ; 0,5]retry_options: nil,{}, clés toutesnil: 3 requêtes (comportement du ticket 01) et options normalisées exactement{max_retries: 2, base_delay: 0.5, max_delay: 8.0}ArgumentErrordès la construction, avec un message nommant la clé en cause →:max_retrie, clé String,max_retries2.5 / -1, délais -1.0 / "x",retry_optionsnon-Hash — surClientetJevTypesafe::Jev.newaccepteretry_options:et le transmet → options normalisées/figées + comportement reflété (tentative unique,base_delayréglé)👀 Comment vérifier
bundle exec rspec spec/typesafe/client_spec.rb -e "retry_options"— scénarios de configuration, validation et gelTypesafe::Jev.new(api_key: k, retry_options: { max_retries: 0 })face à un 429 lève immédiatement, là où le défaut rejouerait deux fois🧪 Vérifications
Typesafe::Client#evaluate/Typesafe::Jev#evaluate(WebMock sur l'endpoint + stub de sommeil, délais observés via les sommes demandées) — cf.## Décisions de testde la specruby --parser=prism -csur lib + spec)Signalements
[NIT]de la revue (cycle 1, verdict APPROVED), non bloquants, non corrigés ici :validate_delay!:value.respond_to?(:>=)est toujours vrai (Object#>=existe) — la garde est morte et le rejet d'unComplexest un accident de la sémantique de>=, pas le check « non ordonnable » commenté ; à réécrire ou documenter honnêtementRETRIES/BASE_DELAY/MAX_DELAYne servent plus qu'à initialiserDEFAULT_RETRY_OPTIONS— indirection collapsable en une seule constanteNoul/Choicenormalisent String→Symbol — défendable (config de politique, pas données du domaine), choix à acterJev.evaluate(state:, questions:, api_key:)n'accepte pasretry_options:— le ticket ne vise queJev.new; à noter pour la doc (ticket 05)retry_options:et l'exemple Errors re-roule encore une boucle manuelle — dette doc portée par le ticket 05📚 Références
docs/plans/retry-client/spec.mdepic-6/03-erreurs-connexion←epic-6/04-retry-options