google / google/guice

Deadlock in multi-threading enviroment (Guice 5.1)

Offen
#1,663 2 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Java
Sterne
12.7k
Forks
1.7k
Ø Merge
11 Min.
Gemergte PRs (30 T.)
2

Beschreibung

It seems that there might be a deadlock in an environment when multiple binding types (JIT / Constructor / Member) are mixed We have found these thread dumps:
First:
```
qtp558569884-17964
at java.base@17.0.5/jdk.internal.misc.Unsafe.park(Native Method)
at java.base@17.0.5/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:523)
at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:90)
at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:199)
at com.google.common.cache.LocalCache$LoadingValueReference.waitForValue(LocalCache.java:3581)
at com.google.common.cache.LocalCache$Segment.waitForLoadingValue(LocalCache.java:2174)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2038)
at com.google.common.cache.LocalCache.get(LocalCache.java:3952)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4964)
at com.google.inject.internal.FailableCache.get(FailableCache.java:54)
at com.google.inject.internal.MembersInjectorStore.get(MembersInjectorStore.java:69)
at com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:75)
at com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:30)
at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:38)
at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:34)
at com.google.inject.internal.FailableCache$1.load(FailableCache.java:43)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3528)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2277)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2044)
at com.google.common.cache.LocalCache.get(LocalCache.java:3952)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4964)
at com.google.inject.internal.FailableCache.get(FailableCache.java:54)
at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:49)
at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:152)
at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:605)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:943)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:863)
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:300)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:223)
at com.google.inject.internal.InjectorImpl.getProviderOrThrow(InjectorImpl.java:1093)
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1122)
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1087)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1139)
.....
```

and second:
```
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:265)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:223)
at com.google.inject.internal.SingleFieldInjector.(SingleFieldInjector.java:39)
at com.google.inject.internal.MembersInjectorStore.getInjectors(MembersInjectorStore.java:131)
at com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:97)
at com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:40)
at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:49)
at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:45)
at com.google.inject.internal.FailableCache$1.load(FailableCache.java:43)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3528)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2277)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2044)
at com.google.common.cache.LocalCache.get(LocalCache.java:3952)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4964)
at com.google.inject.internal.FailableCache.get(FailableCache.java:54)
at com.google.inject.internal.MembersInjectorStore.get(MembersInjectorStore.java:69)
at com.google.inject.internal.InjectorImpl.getMembersInjector(InjectorImpl.java:1072)
at com.google.inject.internal.InjectorImpl.getMembersInjector(InjectorImpl.java:1082)
at com.google.inject.internal.InjectorImpl.injectMembers(InjectorImpl.java:1061)
```

Unfortunately, our setup is quite huge.. thousands of bindings and quite often we are obtaining instances directly from injector. (we are in a process of transformation to proper DI). So I can't provide you with more details now. I'm trying to create minimal test case for now without luck

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne damit, die im Thread gezeigten Pfade von InjectorImpl, ConstructorInjectorStore und MembersInjectorStore sowie die Verwendung von Guices FailableCache nachzuverfolgen. Erstelle einen minimalen nebenläufigen Testfall, der JIT-, Konstruktor- und Member-Bindings mischt. Die Aufgabe ist erledigt, wenn der Deadlock zuverlässig reproduziert wird und das relevante Verhalten durch einen Regressionstest abgedeckt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.