Add on_give_up callback#127
Merged
Merged
Conversation
kamui
added a commit
that referenced
this pull request
May 26, 2026
- README: document non-firing cases (non-retriable exceptions and retry_if rejection) and handler-raised-error propagation semantics. - README: extend the :aws context example with on_give_up. - CHANGELOG: include the full callback signature, reason symbols, and the false/nil opt-out in the HEAD entry. - Specs: cover Retriable.override(contexts:) dispatch of on_give_up, kernel-extension delegation of on_give_up, and the policy that an exception raised inside on_give_up replaces the original. Builds on feat/on-give-up-callback (PR #127, issue #72). No library code changes; existing implementation already satisfies the behavior.
929d0e5 to
f516ede
Compare
kamui
added a commit
that referenced
this pull request
May 26, 2026
kamui
added a commit
that referenced
this pull request
May 26, 2026
f516ede to
107ed03
Compare
Add an on_give_up callback that runs when Retriable stops retrying after a rescued retriable exception. The callback receives the exception, try number, elapsed time, next interval, and a reason symbol (:tries_exhausted or :max_elapsed_time). This covers both final-failure callbacks and max_elapsed_time observability, while preserving on_retry ordering and opt-out semantics with on_give_up: false. Thread the option through config, local options, contexts, with_override, and the kernel extension. Document the API and add coverage for firing paths, non-firing paths, context/override plumbing, and handler error behavior. Closes #72. Closes #76.
107ed03 to
913cec0
Compare
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.
Summary
Introduces an
on_give_upcallback that runs once when Retriable stops retrying after a rescued retriable exception. The callback receives(exception, try, elapsed_time, next_interval, reason), wherereasonis:tries_exhaustedor:max_elapsed_time.Targets the
4.xbranch and inherits its Ruby 3.0+ minimum plus 4.0 timeout-option removal.This single callback covers both requested features:
on_retrywhich fires after every rescued attempt.max_elapsed_time. Thereasonargument distinguishes this case from:tries_exhausted, andnext_intervalreports the would-have-been sleep so users can log how close they were to the budget.Design decisions
on_give_upmirrors the existingon_retryshape (on_<event>).on_retry's 4-arity then addsreasonas the 5th argument. Procs ignore extra args, so existing handler patterns translate directly.on_retryandon_give_upare configured,on_retrystill runs first for the final rescued exception. This preserves existingon_retrysemantics (it runs whenever Retriable rescues a retriable exception).:on, nor when:retry_ifreturns false. Both are immediate re-raises, not retry exhaustion.on_give_up: false(ornil) to suppress a configured handler for a single call, mirroringon_retry's existing semantics.on_give_uppropagates and replaces the original retried exception (same policy ason_retry, now documented).elapsed_timeis re-read afteron_retryreturns so handler-induced delay counts toward themax_elapsed_timebudget for the give-up decision.Implementation
on_give_upattribute onConfig::ATTRIBUTES(defaultnil). Threads throughconfigure, per-call options,with_context,with_override, and per-contextwith_overridevia the existingATTRIBUTESplumbing.can_retry?refactored intoretry_stop_reason, returning the reason symbol ornil. Cleaner because it folds "should we stop?" and "why?" into a single decision point.call_on_give_uphelper mirrorscall_on_retry, including thefalse/nilshort-circuit.4.x; the callback path uses the Ruby 3+/4.0 retry loop without the removedtimeout:plumbing.on_give_upsubsection in Callbacks; options-table row; explicit documentation of non-firing cases, handler-raises behavior, and an extended Contexts example..rubocop.yml: bumpNaming/MethodParameterName.MinNameLengthto 2 so existing single-letter params (on,e) remain acceptable in the new helper signatures.Test Plan
bundle exec rspec— 143 examples, 0 failures.bundle exec rubocop lib spec— 11 files inspected, no offenses detected.Coverage includes:
:tries_exhausted,:max_elapsed_time) with full argument-shape assertions.:on,retry_ifrejects, and hash:onmessage mismatch.on_give_up: false.on_retryruns beforeon_give_upfor the final exception.with_context, top-levelwith_override, per-contextwith_override, andKernel#retriabledelegation.