Skip to content

GODRIVER-2109 Prevent a data race between connecting and checking out a connection from the resourcePool. #728

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

Merged

Conversation

matthewdale
Copy link
Collaborator

@matthewdale matthewdale commented Sep 1, 2021

GODRIVER-2109

There is currently a data race on the field connection.desc between setting it at connection.go#L231 and reading it at pool.go#L199 and pool.go#L535. The data race occurs when the resourcePool.Maintain() function adds connections to satisfy minPoolSize (only when minPoolSize > 0). The unconnected connections are added to the resourcePool and then connected in a separate goroutine, which results in concurrent access to the connection.desc field when another goroutine attempts to get the connection from the resourcePool.

Changes:

  • Add a mutex to connection that guards access to the desc field, preventing a data race between setting and reading the value.
  • Add a test that triggers the data race when run with the data race detector enabled.

Note that the logic for determining if a connection is stale based on the poolGenerationMap is intentionally unchanged. There is currently no way to know exactly what state a connection is in while conn.connected == connected without waiting for conn.wait(), which may take an indefinite amount of time. Instead, we preserve the existing behavior until the refactor in GODRIVER-2038.

Copy link
Contributor

@divjotarora divjotarora left a comment

Choose a reason for hiding this comment

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

LGTM if this resolves the data race.

Copy link
Contributor

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

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

LGTM, and thank you for the explanation of the issue in the description.

Note that the logic for determining if a connection is stale based on the poolGenerationMap is intentionally unchanged. There is currently no way to know exactly what state a connection is in while conn.connected == connected without waiting for conn.wait(), which may take an indefinite amount of time. Instead, we preserve the existing behavior until the refactor in GODRIVER-2038.

I do not fully understand why the staleness check occurs before the connection is connected. But I believe the change set here solves race described.

@matthewdale matthewdale merged commit 33fac98 into mongodb:master Sep 1, 2021
matthewdale added a commit that referenced this pull request Sep 1, 2021
matthewdale added a commit that referenced this pull request Sep 1, 2021
faem pushed a commit to kubedb/mongo-go-driver that referenced this pull request Mar 17, 2022
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.

3 participants