-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bidirectional grpc stream issues on transport is closing
#4578
Comments
It would be useful to see your client code as well, since it sounds like what you're doing is somewhat unusual.
This should be fine;
If the connection is actually lost, then on the server side the RPC's context will be canceled and I can't tell from what is provided why your servers would be getting stuck on RPC operations. It might be helpful to create a minimal reproducible example for both client & server to help narrow it down. |
This is a simplified version. I don't have access to the full code at the moment can revisit on Monday.
|
I've read about this a lot and I assume it's for memory leaks but can it cause the side effects i'm mentioning though?
Could it be that we are not checking the context on the server side (we actually aren't) then or would that cause Send/Recv to error automatically anyway? In any case from what you are saying it sounds like whatever the client does, if the connection is dropped (with the error i've described) the server should gracefully finish the service handler execution without hanging for any reason. Is there any possible way the server hangs due to something the client does? |
Yes, and it's for just generally following best practices. It's possible to safely not do this, but I wouldn't recommend it. No, it shouldn't matter here, but if you have a bug in your client, then this can help ensure the RPC is properly closed.
In your case, yes, because you say you are always blocked on only a
If the client just sits there and doesn't close the stream or connection, then yes. Otherwise no. |
There are a couple DB operations between Send/Recv and another DB operation on ENDSTREAM in the server handler. |
This sounds wrong to me. Anything blocking on the server needs to block on the RPC context or a context derived from it. |
What if you need to do an operation though after the stream is closed / RPC cancelled but before returning from the service handler? Hmm could it be that the stream is actually never cleared completely on the client side because of |
This issue is labeled as requiring an update from the reporter, and no update has been received after 6 days. If no update is provided in the next 7 days, this issue will be automatically closed. |
The act of returning from the service handler is the only thing that ends the RPC. If this is a goroutine spawned from the handler function, then it does make sense to use the background context for those types of operations. (Actually it would probably be best to use a context derived from the handler's, but not canceled - like what is proposed here: golang/go#40221 - but no such thing exists right now.) |
This issue is labeled as requiring an update from the reporter, and no update has been received after 6 days. If no update is provided in the next 7 days, this issue will be automatically closed. |
I have a bidirectional grpc stream set up with the server rpc handler looking something like the following:
and a client that:
Send()
and waits for the responseSend()
and then callsCloseSend()
when it's time to terminate the streamWhenever the client receives an error back it closes the current connection, garbage collects the stream and then creates a new client connection and rpc stream. It seems that the current setup has some issues in which when the client receives a connection dropped error
code = Unavailable desc = transport is closing
then the stream is closed but the server rpc handler never finishes (or it takes veeery long). This was observed because there's a lock on the server handler that is never unlocked but details are not really relevant.I'd like to understand how these streams actually terminate as it's quite confusing reading the docs. Possible interpretations of this issue are:
stream.Send()
on the server and then it was hanging onRecv()
but shouldn'tRecv()
return an EOF since the client has garbage collected the stream anyway?CloseSend()
never really succeeds. Also even though there is only one stream at a time this stream uses a parent context that is never actually cancelled. Again though shouldn't garbage collection handle all this?The text was updated successfully, but these errors were encountered: