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
Use a worker-specific random source to remove lock contention. #178
Conversation
4254d3c
to
1bcf5eb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, this looks great. I added a few nit-pick but otherwise this looks ready to go.
and run TestShouldSample subtests in parallel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR !
@@ -59,7 +71,7 @@ func (w *worker) processMetric(m metric) error { | |||
} | |||
|
|||
func (w *worker) shouldSample(rate float64) bool { | |||
if rate < 1 && rand.Float64() > rate { | |||
if rate < 1 && w.random.Float64() > rate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matthewdale @hush-hush Shouldn't we have a local lock here? From the docs:
The default Source is safe for concurrent use by multiple goroutines, but Sources created by NewSource are not.
I think this is causing race conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct. When MutexMode
is enabled, the call to worker.processMetric()
is made from the same goroutine as the call to the top-level metric emit function (e.g. Count
). I was previously under the impression that all calls to worker.processMetric()
would be made from a single goroutine per worker, but that's not the case.
I'm working on a fix for the data race bug and will submit it when it's ready.
What does this PR do ?
Use a separate random number source per worker. Currently, the
worker
functionshouldSample()
callsrand.Float64()
, which uses a lock to serialize all calls to the package-global pseudorandom number generator, creating lock contention between all instances ofworker
.Changes:
worker
to remove the lock contention Use of rand.Float64() reduces parallelism #80shouldSample()
function to assert that it returnstrue
the expected percentage of the timeshouldSample()
function to measure improvement from removing lock contentionBenchmarks against master