spring-cloud / spring-cloud/spring-cloud-commons
DeadLock on simultanously accessing uninitialized RefreshScope-Bean
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 751
- Forks
- 744
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 9
Description
Hi!
I'm using version 2.0.0.M9. Sometimes my application runs into a deadlock. This happens when two threads are simultanously accessing an uninitialized RefreshScope Bean.
My application uses the annotations NewSpan and Async . Both annotations cause access to a ProbabilityBasedSampler, that's provided as RefreshScope-Bean by ZipkinAutoConfiguration.RefreshScopedProbabilityBasedSamplerConfiguration.defaultTraceSampler(SamplerProperties).
Thread 1 creates a Singleton-Bean, with a @PostConstruct calling a sampled method (@Async-annotation). Thread 2 calls a sampled method (@NewSpan-annotation). ProbabilityBasedSampler and SamplerProperties are not yet initialized.
This is what happens:
-
Thread 1: tries to create the Singleton, accesses
DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory<?>)and locksDefaultSingletonBeanRegistry.singletonObjects -
Thread 2: calls a
@NewSpan-annotated method. This requires theProbabilityBasedSamplerand triggersGenericScope.BeanLifecycleWrapper.getBean()and locksGenericScope.BeanLifecycleWrapper.name -
Thread 2: to create
ProbabilityBasedSamplertheSamplerPropertiesare required. The bean factory tries to get theSamplerProperties-Singleton, but has to wait for the lock onDefaultSingletonBeanRegistry.singletonObjectsthat is held by Thread 1 -
Thread 1: the
@PostConstructcalls a@Async-annotated method, that requiresProbabilityBasedSampler. that triggersGenericScope.BeanLifecycleWrapper.getBean(), but has to wait for the lockGenericScope.BeanLifecycleWrapper.nameheld by Thread 2
I attach a class that simulates the behaviour of my application setup and the stack trace when this class runs into the deadlock: RefreshScopeDeadLock.zip
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Unpack RefreshScopeDeadLock.zip and start with the included reproducer and stack trace. Trace the two-thread interaction through DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory<?>) and GenericScope.BeanLifecycleWrapper.getBean(), focusing on ProbabilityBasedSampler and SamplerProperties initialization. Done means the reported simultaneous access no longer deadlocks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100