Skip to content

fix: use monotonic clock for elapsed time and handle nil max_elapsed_time#122

Merged
kamui merged 3 commits intomainfrom
fix/timing-safety
Mar 9, 2026
Merged

fix: use monotonic clock for elapsed time and handle nil max_elapsed_time#122
kamui merged 3 commits intomainfrom
fix/timing-safety

Conversation

@kamui
Copy link
Owner

@kamui kamui commented Mar 9, 2026

Summary

  • Monotonic clock: Replace Time.now with Process.clock_gettime(CLOCK_MONOTONIC) for elapsed-time tracking in the retry loop. Wall-clock time (Time.now) is susceptible to NTP adjustments and manual system clock changes, which can cause retries to stop early or run too long. Monotonic clock is the correct primitive for measuring durations.

  • Nil-safe max_elapsed_time: Guard can_retry? so that max_elapsed_time: nil means "no time limit" instead of raising NoMethodError on the <= comparison. This is a runtime crash that only manifests after a failure+retry, making it easy to miss in testing.

  • Remove dead * 1.0: The randomize method in ExponentialBackoff multiplied by 1.0 unnecessarily — rand_factor is already a float.

Testing

  • Two new regression specs: one verifying max_elapsed_time: nil retries up to tries limit, one verifying Process.clock_gettime(CLOCK_MONOTONIC) is called during retries.
  • All 59 specs pass. No RuboCop offenses on changed files.

…time

- Replace Time.now with Process.clock_gettime(CLOCK_MONOTONIC) so retry
  timing is immune to wall-clock adjustments (NTP, manual changes).
- Guard can_retry? against max_elapsed_time: nil, which previously raised
  NoMethodError on the comparison path.
- Remove dead '* 1.0' in ExponentialBackoff#randomize (rand_factor is
  already a float).
- Add regression tests for both fixes.
Copilot AI review requested due to automatic review settings March 9, 2026 23:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the reliability and configurability of Retriable’s retry loop by switching elapsed-time tracking to a monotonic clock and making max_elapsed_time nil-safe to avoid runtime crashes during retries.

Changes:

  • Use Process.clock_gettime(Process::CLOCK_MONOTONIC) instead of Time.now for elapsed-time measurement.
  • Treat max_elapsed_time: nil as “no elapsed-time limit” in retry eligibility checks.
  • Simplify exponential backoff randomization math by removing a float-coercion multiplier.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
spec/retriable_spec.rb Adds regression specs for max_elapsed_time: nil and monotonic clock usage.
lib/retriable/exponential_backoff.rb Removes * 1.0 from randomization calculation and minor expression tweak.
lib/retriable.rb Switches elapsed-time tracking to monotonic clock; makes can_retry? nil-safe for max_elapsed_time.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kamui kamui merged commit c19ac3c into main Mar 9, 2026
13 checks passed
@kamui kamui deleted the fix/timing-safety branch March 9, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants