-
Notifications
You must be signed in to change notification settings - Fork 780
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
Possible deadlock with bidirectional streaming #2576
Comments
HTTP/2 flow control request and response use different buffers. A server that isn't reading request data fast enough shouldn't impact its ability to send response data. https://medium.com/coderscorner/http-2-flow-control-77e54f7fd518 |
Hello @JamesNK. |
The server might not be able to send the complete response because the buffer fills up, so it's waiting for the client to read it. |
@JamesNK Yes, that's definitely the case. |
I've ran out of ideas. |
Well. actually no. It's working. But because of full buffer, there is no update window and the whole system goes deadlock. Is it correct behavior? |
Hello.
Got interesting problem with bidirectional streaming through grpc connection in .Net.
I have three servers, like client <-> client-server <-> server.
client write in request stream requests, client-server process it (sort of), and server makes another requests to third party services (which is kinda slow). Problem occures when i write to request stream on client several dozens big requests (about 35-37 kb), server (through client-server) receives it, and starts process it. I think i should say that producer (client) is much faster than consumer (server).
Server relies on
await foreach IAsyncEnumerable
, so it reads first message, process it, write response to response stream and then read next request. But after processing first request, he can not write response to response stream, and consequently it can not read another request. I believe it's because ofGRPC_ARG_HTTP2_WRITE_BUFFER_SIZE
parameter which is 65k by default. And if channel buffer is full of requests, there is literally no space for response, which is, basically, a deadlock. The most obvious solution - read all from request channel, store this request in some array and then just foreach it. But, unfortunately, this project has a use case, when server uses response data as a request for another service, and response is, basically, this data with some enrichments.So with this case in mind, i can not use obvious solution, because in that case i would store all response in memory. And it can be hundreds of megabytes.
I tried to increase
InitialHttp2StreamWindowSize
inSocketHttpHandler
which i use forGrpcChannel
creation, to it maximum and it resolves the problem, but i realize it is a temporary solution. SettingEnableMultipleHttp2Connections
in the sameSocketHttpHandler
doesn't help at all.I created MRE for ensuring that this is not our code peculiarity
Is there some more permanent solution? Or i just do smth wrong?
I'm using Grpc.AspNetCore 2.63.0
OS: Macos Sonoma 14.1.1
Device: Macbook pro m1
Dotnet: 8.0.300
MRE: https://drive.google.com/file/d/13JFrQp8KeSNZ6D8TQJjpKl5rNbaBYB7s/view?usp=drive_link
The text was updated successfully, but these errors were encountered: