question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Get client disconnect notifications in bidirectional async gRPC

See original GitHub issue

We don’t get any notification when the client closes the connection when using asynchronous bidirectional stream calls.

https://github.com/SourceForgery/tachikoma/blob/ddfb03ba5d25f3de61e8fe1e1b2cb9be2aba0eb4/tachikoma-grpc/src/main/kotlin/com/sourceforgery/tachikoma/mta/MTAEmailQueueService.kt#L31

We get neither onComplete(), nor onError() in the ~ResponseObserver~StreamObserver when the client closes the socket.

Just to clarify the code, the getEmails() method will return immediately, but will hook up a listener to the RabbitMQ which will then deliver messages via responseObserver.onNext(response). The RabbitMQ will stop delivering messages when the future is finished (which will only happen in response to exceptions or close).

The lifetime of this call is counted in months, as it’s more of a subscription than anything else.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
tobias-commented, Jan 24, 2018

It is not.

~I’m really not sure about this, but it seems that when doing HttpServerHandler.handleRequest() there’s a lot of logic used to find the correct Service and call it, but when coming back asynchronously later in HttpServerHandler.channelInactive(), that context is gone, although the ChannelHandlerContext is still available.~

~It doesn’t seem that the HttpServerHandler is shut down properly in the case of closed socket, as unfinishedRequests is never counted down to 0 nor is gracefulShutdownSupport.~

All that said (and while true, I believe it to be irrelevant), I looked at how the stream objects/data is propagated, and that uses the Http2RequestDecoder. Armeria does get a callback when the client closes the socket as a Http2RequestDecoder.onStreamRemoved(), which imho should be propagated a lot more.

Could something as simple as this work? (cloning armeria and testing)

     @Override
     public void onStreamRemoved(Http2Stream stream) {
-        requests.remove(stream.id());
+        final DecodedHttpRequest req = requests.remove(stream.id());
+        if (req != null) {
+            req.close();
+        }
     }
0reactions
tobias-commented, Jan 24, 2018

Ok, that fix works for me. I’m none too fond of signing license agreements, so if somebody who has signed it can open a PR with that, please do. I consider the above code trivial and therefore not copyrightable. Do what you want with it.

I’ve run all the tests and they pass. This code also makes sure that the HttpServerHandler mentioned above is closed seemingly properly, and that propagates into ResponseObserver.onComplete() which is exactly where I would expect it to end up, since it isn’t an error.

Example commit message:

Close the requests associated with killed stream

When a socket is closed, make sure that the outstanding requests
(unfinishedRequests) are closed/terminated as well by closing
the stream when removing it.

Closes #971
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to detect (physical) disconnect when using a bidirectional ...
I have using Bidirectional Streaming concept of Grpc using Async stub . Following is my code @Override protected void onCreate( ...
Read more >
Core concepts, architecture and lifecycle - gRPC
An introduction to key gRPC concepts, with an overview of gRPC architecture and RPC life cycle.
Read more >
Call gRPC services with the .NET client - Microsoft Learn
A bi-directional streaming call starts without the client sending a message. The client can choose to send messages with RequestStream.
Read more >
Streaming with gRPC in Java - Baeldung
Bidirectional streaming RPC: The client and server can send multiple messages back and forth. The messages are received in the same order that ......
Read more >
The Mysterious Gotcha of gRPC Stream Performance | Ably Blog
gRPC is highly useful for fast, efficient data exchange and client/server state sync. Here's a performance gotcha we ran across.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found