Skip to content

Bound individual condition waits for very large timeouts - #120

Open
OskarEichler wants to merge 1 commit into
ruby:masterfrom
OskarEichler:codex/waits-timeout
Open

Bound individual condition waits for very large timeouts#120
OskarEichler wants to merge 1 commit into
ruby:masterfrom
OskarEichler:codex/waits-timeout

Conversation

@OskarEichler

Copy link
Copy Markdown

Summary

Cap each internal condition-variable wait at one day while retaining the original monotonic deadline. Large positive/infinite timeouts otherwise raise RangeError inside the shared watcher and discard its active request set.

Reproduction

require 'timeout'
ready, finish = Queue.new, Queue.new
worker = Thread.new do
  Timeout.timeout(1e100) { ready << true; finish.pop }
end
ready.pop
sleep 0.05
watcher = Timeout.const_get(:State).instance.instance_variable_get(:@timeout_thread)
p watcher.alive? # before: false (RangeError); after: true
finish << :done
worker.join
watcher.kill.join if watcher.alive?

Run this standalone reproduction in a disposable process; it inspects/stops that process's private watcher. No external services are used.

Focused checks cover Float::INFINITY, 1e100, a large Integer and Rational, and a finite interval exceeding one day. After each long request starts, a short request still wakes the watcher and times out; the long operation can finish normally. This verifies signaling, not a literal 24-hour elapsed-time run.

Verification

  • Ruby 4.0.6 via rbenv; reviewed master 295667aac44220ddfd10db014e766ae8d313cfb8.
  • Existing bundle exec rake test: 36 tests / 81 assertions / zero failures or errors, baseline and this branch. Includes the existing signal, fork, Ractor, exception and mocked-scheduler cases.
  • waits: 15 checks, 0 failures in a disposable external script, with the affected expectations reproduced before the change.
  • Syntax and git diff --check pass. Supplemental RuboCop Lint retains the same two existing offenses; no lint-clean claim.
  • No repository tests added/modified, following the consuming project's explicit no-new-tests instruction. Standalone reproduction is included above.
  • Existing issues/PRs checked, including multi threaded use of timeout leads to OOM on high throughput scenarios #58 throughput, Handle nested timeout calls with the same duration #91 nested-timeout draft, Ensure thread is released on completion #114 completed-thread retention, and historic comparison/deferred-exception changes. No duplicate retention or nested-timeout proposal.

Compatibility and limitations

No timeout value or deadline is shortened. Very long operations may cause a periodic internal wakeup, at most once per day when otherwise idle. Existing queue signals still wake the watcher for shorter deadlines. The one-day wait is deliberately far below platform time-conversion limits. Ruby 4.0.6/macOS was run; other platforms require CI. NaN rejection is handled separately.

The same runtime file is shipped in 0.6.1; this patch can be adopted without a release upgrade. Ruby >= 2.6 and the empty runtime dependency set remain unchanged. No production access or external network diagnostic was used; other Ruby/OS combinations and full scheduler implementations were not run locally.

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.

1 participant