Make Pool safe for use by multiple goroutines #498
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reason for the change
Fixes #497
Description
WARNING: this might be a breaking change for some applications.
To be specific, if an application calls Query() from N goroutines
but doesn't close the returned cursors, and is using a pool with
fewer than N entries, the last call will block forever.
Needless to say README.md already recommends closing cursors to
prevent leaking connections, so developers were warned...
Pool entries are acquired with "non blocking mutexes" to
promote concurrency.
Remote queries are not fast compared to the instructions on the
local processor. It would be preferable to use sync.Cond so
goroutines waiting for a connection could sleep until one becomes
available. However, that introduces a race condition I wasn't able
to resolve without a (blocking) mutex. If every connection is busy,
the pool waits before trying again.
The wait logic can be overridden by the library user, since
applications have different workloads; batch loading is quite
different from individual queries serving a UI. A developer can
implement a fixed delay, exponential delay, etc. in tandem with
delay constants appropriate for their application.
Code examples
Checklist
References