-
Notifications
You must be signed in to change notification settings - Fork 419
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
concurrent requests cause StreamIDTooSmall error, channel state becomes transientFailure #912
Comments
The underlying issue is in swift-nio-http2, as I discussed in apple/swift-nio-http2#213. However, the fix there is complex, so we should consider whether we can work around the issue in grpc. There are two possible workarounds that I can see. The first is to apply a queue in grpc to ensure that we flush data in the order we create the streams. This is annoying, but can work. The second is even easier: just consider @glbrntt, thoughts? |
@Lukasa I like the simplicity of just retrying, but Unless I'm missing something we'd have to make changes to NIOHTTP2 (namely: add the streamID to the error and route that error into the relevant stream via the multiplexer) to allow for this. It'd at least enable other HTTP/2 users to work around this in the same way. |
Hmm, yeah, that's gonna be trickier. Let's chat about this today. |
@i9 just to provide an update: we decided to fix this in NIOHTTP2 rather than working around it in gRPC. The issue tracking this is: apple/swift-nio-http2#214 |
really appreciate the swift action 😉 |
This bug is easy reproduce on iOS device (on Simulator this happens very rarely) using
|
@givip There is no evidence in that log of this error occurring. Is there any evidence elsewhere? |
This log:
Note the presence of the string |
@Lukasa I don't have this error's mention, but it seems that bug behavior is the same. I start two simultaneous requests and the second never performs, after some amount of time if fails with error |
The symptom may be the same but without that log it cannot be this issue. |
Motivation: The multiplexer from SwiftNIO HTTP/2 required that the first write on each stream matched the order in which the streams were created. Violating this led to a connection error; all in-flight and subsequent RPCs on that connection would fail. Some of our users noticed this (grpc#912). SwiftNIO HTTP/2 recently reworked the API around how streams are created: HTTP/2 stream channels are no longer created with a stream ID and now deliver the frame payload to the channel pipeline rather than the entire HTTP/2 frame. This allows for a stream ID to be assigned to a stream when it attempts to flush its first write, rather than when the stream is created. Modifications: - Increase the minimum HTTP/2 version to 1.13.0 - Move away from deprecated APIs: this required changing the inbound-in and outbound-out types for `_GRPCClientChannelHandler` as well as a few smaller changes elsewhere. Result: - RPCs can be created concurrently without fear of violating any stream ID ordering rules - Resolves grpc#912
Motivation: The multiplexer from SwiftNIO HTTP/2 required that the first write on each stream matched the order in which the streams were created. Violating this led to a connection error; all in-flight and subsequent RPCs on that connection would fail. Some of our users noticed this (#912). SwiftNIO HTTP/2 recently reworked the API around how streams are created: HTTP/2 stream channels are no longer created with a stream ID and now deliver the frame payload to the channel pipeline rather than the entire HTTP/2 frame. This allows for a stream ID to be assigned to a stream when it attempts to flush its first write, rather than when the stream is created. Modifications: - Increase the minimum HTTP/2 version to 1.13.0 - Move away from deprecated APIs: this required changing the inbound-in and outbound-out types for `_GRPCClientChannelHandler` as well as a few smaller changes elsewhere. Result: - RPCs can be created concurrently without fear of violating any stream ID ordering rules - Resolves #912
Describe the bug
grpc-swift version 1.0.0-alpha.17, swift-nio-http2 from: "1.12.1"
grpc-swift client(iOS App) --- nginx --- grpc server
client sends 3 different rpcs almost at the same time, one failed due to StreamIDTooSmall, the other two failed due to unavailable. error log:
But from nginx log, 2 out of 3 responses are returned successfully. one had error due to
client prematurely closed connection while processing HTTP/2 connection
which we assume is due to client side close and reconnect.we suspect in swift-nio-http2 createStreamChannel,
self.nextOutboundStreamID = HTTP2StreamID(Int32(streamID) + 2)
isn't thread safe, but we couldn't find any doc or guidance what to do.To reproduce
Steps to reproduce the bug you've found:
Expected behaviour
All requests succeeded.
Additional information
about 15% of our users are seeing the error. If it's the api caller's responsibility to avoid concurrent requests, we would like to see the doc clearly mention that.
I also filed apple/swift-nio-http2#213 but unsure which repo will fix the issue (if it's indeed a bug)
The text was updated successfully, but these errors were encountered: