grpc / grpc/grpc-java

StreamObserver.onError() call on different instance when client gets SIGKILL (CANCELLED: client cancelled)

Aperta
#9,996 10 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Java
Stelle
12.1k
Fork
4k
Merge medio
2g 17h
PR unite (30g)
37

Descrizione

I have an ongoing bidirectional stream between my client and my server. I then terminate my client with SIGKILL. This leads to a `io.grpc.StatusRuntimeException: CANCELLED: client cancelled` and a call to my `onError()` implementation of the `StreamObserver` on the server-side. My issue is that the call is not executed on the same `StreamObserver` instance as `onNext()` earlier. This leads to the problem that some attributes in my StreamObserver implementation are `null` during the `onError()` call instead of the values I set them to earlier. This does not happen when for example an exception is thrown during the `onNext()` execution. In this case the `onError()` is executed on the same instance. I'm using the `@Scope(scopeName = "grpcRequest", proxyMode = ScopedProxyMode.TARGET_CLASS)` notation above my class. While debugging I noticed that the instance gets destroyed right before the `onError()` call and the application logging the `StatusRuntimeException: CANCELLED: client cancelled`. I raised the issue already with the grpc-spring-boot-starter project as yidongnan/grpc-spring-boot-starter#870, as I was not sure if this is the right place or if this behaviour is intended, but it seemed rather strange to me. The kind maintainer of the project deducted that this should be an issue with the request scope, that should be valid at this point, but is no longer. Therefore I'm opening this issue.

For my needs I found a way to circumvent the issue with the Javax annotation `@PreDestroy` in my `StreamObserver`, in case anybody else is having the same issue.

### What version of gRPC-Java are you using?
grpc-java: 1.51.0
### What is your environment?
* Spring (boot): 2.6.13
* grpc-spring-boot-starter: 2.14.0.RELEASE
* java: 18.0.2 64 Bit

### What did you expect to see?
That the `onError()` call is executed on the same instance

### What did you see instead?
It was executed on a different instance.

### Steps to reproduce the bug

Ongoing bidirectional stream between server and client. Send SIGKILL to the client and log the instance on the server-side like below.

To make my issue more clear if I log the instance (with `System.out.print("SOME STRING" + this)`) my methods are called during the bidirectional stream would look like something like this:

```
onNext() call instance: ClassName@AAAA
onNext() call instance: ClassName@AAAA

[the clients gets SIGKILL in the meatime]

onError() call instance: ClassName@BBBB
```

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia riproducendo il caso di stream bidirezionale con StreamObserver, @Scope(scopeName = "grpcRequest") e un client terminato da SIGKILL. Confronta le identità delle istanze di onNext() e onError() e osserva il momento di @PreDestroy. Il lavoro è completato quando si è stabilito se onError() lato server debba usare la stessa istanza scoped e il comportamento del ciclo di vita è stato documentato o corretto.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
java, spring
Ambito
backend-api-design, networking
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
32/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.