Race condition when creating HystrixThreadPool#340
Merged
benjchristensen merged 1 commit intoNetflix:masterfrom Dec 11, 2014
Merged
Race condition when creating HystrixThreadPool#340benjchristensen merged 1 commit intoNetflix:masterfrom
benjchristensen merged 1 commit intoNetflix:masterfrom
Conversation
…n HystrixThreadPoolMetrics and different one used for executing commands
|
Hystrix-pull-requests #169 FAILURE |
Contributor
|
Great bug report, thank you for fixing this. |
benjchristensen
added a commit
that referenced
this pull request
Dec 11, 2014
Race condition when creating HystrixThreadPool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Symptoms
Different thread pool is referenced in
AbstractCommandand a different one inHystrixThreadPoolMetricsfor the same key. This means monitoring always shows0in active thread, etc. because that pool is never touched. This happens only when pool is first initialized from multiple threads. Pseudo code exposing bug:Code above shows correct pool statistics because second line safely initialized one thread pool. However if second line is commented, race condition causes different thread pool to be registered for statistics and different one for actual execution. I believe I can turn this into a test-case if necessary.
Steps to reproduce:
HystrixThreadPool.Factory.getInstance()viaAbstractCommandc-torthreadPoolsstatic map is empty for both threads, thus they both hitthreadPools.putIfAbsent(key, new HystrixThreadPoolDefault(...));HystrixThreadPoolDefaultare created eagerly, first one (arbitrary) registers itself inHystrixThreadPoolMetrics.metricsinsideHystrixThreadPoolMetrics#getInstance(...)HystrixThreadPool.Factory.getInstance()this:threadPools.putIfAbsent(key, ...)is executed. However there is no guarantee thatthreadPools.putIfAbsent()will put the same thread pool as the one inHystrixThreadPoolMetrics.metricsSeverity
This bug is not critical, but causes dashboard to show incorrect statistics.
Fix
My fix is straightforward: just put
synchronizedaround lazy initialization. Previous code was more clever and probably faster - but broken. I understandsynchronizedwas almost absent in this class, moreover we already deal with thread-safe collections. I considered another approach: instead of eagerly creating newHystrixThreadPoolDefaultinputIfAbsent(), use another (new) implementation ofHystrixThreadPoolas a marker:But this seems hacky and hard to read. Also by introducing second implementation of
HystrixThreadPoolJVM can't make such aggressive optimizations (inlining) due to multiple implementations loaded. This is largely a premature optimization.