Skip to content

Wake blocked checkout callers when a connection is discarded - #219

Open
OskarEichler wants to merge 1 commit into
mperham:mainfrom
OskarEichler:codex/wake-discard-waiters-upstream
Open

Wake blocked checkout callers when a connection is discarded#219
OskarEichler wants to merge 1 commit into
mperham:mainfrom
OskarEichler:codex/wake-discard-waiters-upstream

Conversation

@OskarEichler

Copy link
Copy Markdown

Summary

Wake blocked checkout callers when discarding a connection releases capacity. TimedStack#decrement_created now updates the count under the existing mutex and broadcasts to waiting callers, like the normal checkin path.

Previously, a size-one pool could discard its only connection while another caller remained asleep until the full checkout timeout, despite replacement capacity being available.

Reproduction

require 'connection_pool'
pool = ConnectionPool.new(size: 1, timeout: 0.5) { Object.new }
ready = Queue.new
worker = nil
pool.with do
  worker = Thread.new do
    ready << true
    started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    pool.with { puts Process.clock_gettime(Process::CLOCK_MONOTONIC) - started }
  end
  ready.pop
  Thread.pass until worker.status == 'sleep'
  pool.discard_current_connection
end
worker.join
pool.shutdown { |_connection| }

On installed 3.0.2: ~0.502 seconds. With the fix: under 0.001 seconds in 20 local rounds. These are an isolated contention reproduction, not a general throughput benchmark.

Verification

  • Ruby 4.0.6: existing suite passes, 86 runs / 187 assertions / zero failures or errors on the release-based patch.
  • Focused repeated wakeup and pool-capacity checks pass.
  • Existing targeted StandardRB, Ruby syntax and git whitespace checks pass.
  • Consumer patch based on v3.0.2; this PR carries only the corresponding focused change on main.

Limitations and breaking changes

  • The release's development setup resolves Minitest 6 without its extracted mock support. Initial suite had four missing-stub errors. An external verification Gemfile adds minitest-mock, as current upstream does. No test, Gemfile or gemspec changes included.
  • No new tests under the consumer's no-new-tests policy; the reproduction and existing suite provide verification.
  • No JRuby/TruffleRuby/Linux runtime checks were run locally; CI should exercise the existing matrix.
  • Breaking changes: none intended. Public API, dependencies and ordinary checkin behavior are unchanged. Waiters can now use replacement capacity promptly.

Prepared with Codex assistance.

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