Skip to content

GODRIVER-3419 Use a semaphore to limit concurrent conn creation #2098

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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

prestonvasquez
Copy link
Member

@prestonvasquez prestonvasquez commented Jun 12, 2025

GODRIVER-3419

Summary

This PR refactors the connection pool to eliminate the persistent maxConnection goroutines spawns at pool construction. Here we adopt a more lightweight, on-demand model inspired by @matthewdale's POC c26a3cb. Each new goroutine is responsible for creating exactly one connection and then terminates immediately.

Background & Motivation

While so-far not reproducible locally, the "spawn-and-done" approach suggested by this PR intends to avoid any long-term memory allocation patterns causing the GC to thrash. See ticket for more information.

@prestonvasquez prestonvasquez requested a review from a team as a code owner June 12, 2025 01:41
@prestonvasquez prestonvasquez marked this pull request as draft June 12, 2025 01:41
@mongodb-drivers-pr-bot mongodb-drivers-pr-bot bot added the priority-3-low Low Priority PR for Review label Jun 12, 2025
Copy link
Contributor

API Change Report

No changes found!

@prestonvasquez prestonvasquez marked this pull request as ready for review June 13, 2025 17:34
Comment on lines +1491 to +1497
func (p *pool) waitForNewConn(ctx context.Context) (*wantConn, *connection, bool) {
p.createConnectionsCond.L.Lock()
defer p.createConnectionsCond.L.Unlock()

for !(p.checkOutWaiting() && p.hasSpace()) && ctx.Err() == nil {
p.createConnectionsCond.Wait()
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Waiting on the createConnectionsCond may cause an unbounded number of goroutines to be paused here.

For example, consider a case where the connection pool is full, so p.hasSpace() always returns false, no connections are closing, and all connections are in-use. A new operation calls checkOut and blocks at p.createConnectionsCond.Wait() until something signals the cond. It seems that a subsequent call to queueForNewConn should signal one of the waiting goroutines, but the behavior of sync.Cond.Signal is nondeterministic, so it's not clear if that will always happen.

Instead, we could immediately stop trying to create a new connection if the pool is full. The checkOut behavior would be the same except if the pool is full, that checkOut would no longer trigger a new connection if another connection is closed while the checkOut is waiting.

My intuition is that the latter case is lower risk, but it's not clear if goroutines getting "stuck" would even be a problem. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority-3-low Low Priority PR for Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants