Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix leaky connections #223

Closed
wants to merge 1 commit into from
Closed

Conversation

tneely
Copy link
Contributor

@tneely tneely commented Oct 14, 2024

Fixes #221

It's possible to trigger more approvals than are necessary, in turn
grabbing more connections than we need. This happens when we drop a
connection. The drop produces a notify, which doesn't get used until the
pool is empty. The first Pool::get() call on an empty pool will spawn
an connect task, immediately complete notify.notified().await, then
spawn a second connect task. Both will connect and we'll end up with 1
more connection than we need.

Rather than address the notify issue directly, this fix introduces some
bookkeeping that tracks the number of open pool.get() requests we have
waiting on connections. If the number of pending connections >= the
number of pending gets, we will not spawn any additional connect tasks.

I have additionally changed notify.notify_waiters(); to a
notify.notify_one(); call in the broken connection branch. A single
broken connection should only need to notify one pending task to spawn a
new connect task, not all of them.
See #225

bb8/src/inner.rs Outdated Show resolved Hide resolved
bb8/src/internals.rs Outdated Show resolved Hide resolved
@djc
Copy link
Owner

djc commented Oct 15, 2024

Thanks for your work on this!

bb8/src/internals.rs Show resolved Hide resolved
bb8/src/internals.rs Outdated Show resolved Hide resolved
bb8/src/internals.rs Outdated Show resolved Hide resolved
bb8/src/internals.rs Outdated Show resolved Hide resolved
bb8/src/internals.rs Outdated Show resolved Hide resolved
Fixes djc#221

It's possible to trigger more approvals than are necessary, in turn
grabbing more connections than we need. This happens when we drop a
connection. The drop produces a notify, which doesn't get used until the
pool is empty. The first `Pool::get()` call on an empty pool will spawn
an connect task, immediately complete `notify.notified().await`, then
spawn a second connect task. Both will connect and we'll end up with 1
more connection than we need.

Rather than address the notify issue directly, this fix introduces some
bookkeeping that tracks the number of open `pool.get()` requests we have
waiting on connections. If the number of pending connections >= the
number of pending gets, we will not spawn any additional connect tasks.
@djc
Copy link
Owner

djc commented Oct 17, 2024

See #226.

@djc djc closed this Oct 17, 2024
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.

pool.get() can acquire more connections than are necessary
2 participants