[sdk-platform-java] Race condition in TracedUnaryCallable causes flaky integration tests
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 68/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- grpc, java
- Ambito
- observability, testing
Direzione di ricerca
Inizia da TracedUnaryCallable e TracedBatchingCallable, poi esamina l’uso dei callback di ApiFutures descritto nell’issue. Esegui ITOtelGoldenMetrics per riprodurre il malfunzionamento delle metriche vuote. Il lavoro è completato quando il future restituito viene completato solo dopo che TraceFinisher ha registrato il successo o il fallimento e il test di integrazione non presenta più errori intermittenti.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Description
In gax-java, observability tracers (such as TracedUnaryCallable and TracedBatchingCallable) use TraceFinisher attached via ApiFutures.addCallback to record metrics and spans upon completion.
ApiFutures.addCallback(future, finisher, MoreExecutors.directExecutor());
This pattern creates a race condition in synchronous environments, such as integration tests (ITOtelGoldenMetrics), where the test thread calls future.get() and immediately asserts state (e.g., checks OpenTelemetry metrics).
Root Cause
When the underlying RPC future completes, the Guava/ApiFuture infrastructure notifies listeners. addCallback attaches a listener that runs independently of the future's resolution state for the blocking caller.
In ITOtelGoldenMetrics:
client.echo()blocks the test thread.- The gRPC network thread completes the RPC.
- The test thread unblocks and calls
metricReader.collectAllMetrics(). - Concurrently (or slightly after), the
TraceFinisherruns to record the metric in the OTel meter.
If the test thread executes before the TraceFinisher completes its work, the test fails with "empty metrics".
Proposed Solution
Convert the detached addCallback into a chained future transformation. This guarantees that the returned future only resolves after the tracer has finished recording metrics/spans.
Example for TracedUnaryCallable:
ApiFuture<ResponseT> onSuccessFuture =
ApiFutures.transform(
future,
response -> {
finisher.onSuccess(response);
return response;
},
MoreExecutors.directExecutor());
return ApiFutures.catchingAsync(
onSuccessFuture,
Throwable.class,
t -> {
finisher.onFailure(t);
return ApiFutures.immediateFailedFuture(t);
},
MoreExecutors.directExecutor());
This approach ensures structural LIFO ordering: the metric is recorded before any downstream consumer can yield from a blocking .get() on the returned future.
- Lingua principale
- Java
- Stelle
- 2.1k
- Fork
- 1.2k
- Merge medio
- 2g 14h
- PR unite (30g)
- 192
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di googleapis/google-cloud-java
-
[java-core] Timestamp.of(java.sql.Timestamp) is one second late for a time less than a second before the epochForse già presa @Vcode2407 l’ha presa 4 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
googleapis/google-cloud-java#14636 ·
I maintainer di solito rispondono entro 1 giorno
-
[java-firestore] UserDataConverter encodes a pre-epoch Date with negative nanos, so the write is refusedForse già presa @wu-hui l’ha presa 23 giorni fa. Apertapriority: p2 type: bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
googleapis/google-cloud-java#14635 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
[java-firestore] UserDataConverter throws IndexOutOfBoundsException on an empty __binary__ valueForse già presa @wu-hui l’ha presa 23 giorni fa. Apertapriority: p2 type: bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
googleapis/google-cloud-java#14634 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
[java-firestore] CustomClassMapper.convertBigDecimal calls .abs() on Double, unintentionally flipping negative values to positiveForse di nuovo libera @wu-hui l’ha presa 45 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
googleapis/google-cloud-java#14533 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Github CI failing when trying to install xmllintForse già presa @blakeli0 l’ha presa 81 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
googleapis/google-cloud-java#14132 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di googleapis/google-cloud-java
Issue simili
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
-
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 84/100
cpp-best-practices/project_validator#251 ·
I maintainer di solito rispondono entro 1 giorno
-
backend enhancement
Difficoltà 2/5 Mezza giornata Idoneità per principianti 70/100
damodharg6/payledger#16 ·
-
[Bug]: An initiative list with no current entry logs an error on every changeForse già presa @dwizard0 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno