grpc: Objective-C gRPC API v2 returning RST_STREAM error
What version of gRPC and what language are you using?
1.27.0, Objetive-C
What operating system (Linux, Windows,…) and version?
Mac OS Mojave, 10.14.6
What runtime / compiler are you using (e.g. python version or version of gcc)
Xcode 11.3
What did you do?
We have a few endpoints written in Go. When I try to send a request to them using the Objective-C gRPC the API v1 (which is deprecated), everything works great:
/* This method belongs to a set of APIs that have been deprecated. Using the v2 API is recommended.
*/
- (void)someCallWithRequest:(XXXCallRequest *)request handler:(void(^)(XXXCallResponse *_Nullable response, NSError *_Nullable error))handler;
However, when I use the new API v2, some of the requests receive the following error:
Error Domain=io.grpc Code=13 "{"created":"@1589553479.630057000","description":"Error received from peer ipv4:x.x.x.x:443","file":"/Users/me/Documents/ourapp/App/Pods/gRPC-Core/src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Received RST_STREAM with error code 2","grpc_status":13}" UserInfo={io.grpc.HeadersKey={
date = "Fri, 15 May 2020 14:37:58 GMT";
server = "nginx/1.17.8";
"strict-transport-security" = "max-age=15724800; includeSubDomains";
trailer = "Grpc-Status";
}, io.grpc.TrailersKey={
}, NSDebugDescription={"created":"@1589553479.630057000","description":"Error received from peer ipv4:x.x.x.:443","file":"/Users/me/Documents/ourapp/App/Pods/gRPC-Core/src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Received RST_STREAM with error code 2","grpc_status":13}, NSLocalizedDescription=Received RST_STREAM with error code 2}.
The new v2 API has this signature:
- (GRPCUnaryProtoCall *)callWithMessage:(XXXCallRequest *)message responseHandler:(id<GRPCProtoResponseHandler>)handler callOptions:(GRPCCallOptions *_Nullable)callOptions;
After further debugging, I concluded a few things:
- The problem never happens with API v1
- The problem happens a lot with API v2, but not always
- The problem never happens if the backend is running locally in my computer
I fear that the bug here is related to the handler being deallocated. I tried a few things to ensure that the handler is not deallocated but without success. Maybe we removed some check from API v1 to v2 that was responsible for holding a handler reference?
What did you expect to see?
I expected to receive a success return to my requests, as the API v1 give.
What did you see instead?
I receive a RST_STREAM with internal_error description:
Error Domain=io.grpc Code=13 "{"created":"@1589553479.630057000","description":"Error received from peer ipv4:x.x.x.x:443","file":"/Users/me/Documents/ourapp/App/Pods/gRPC-Core/src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Received RST_STREAM with error code 2","grpc_status":13}" UserInfo={io.grpc.HeadersKey={
date = "Fri, 15 May 2020 14:37:58 GMT";
server = "nginx/1.17.8";
"strict-transport-security" = "max-age=15724800; includeSubDomains";
trailer = "Grpc-Status";
}, io.grpc.TrailersKey={
}, NSDebugDescription={"created":"@1589553479.630057000","description":"Error received from peer ipv4:x.x.x.:443","file":"/Users/me/Documents/ourapp/App/Pods/gRPC-Core/src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Received RST_STREAM with error code 2","grpc_status":13}, NSLocalizedDescription=Received RST_STREAM with error code 2}.
Anything else we should know about your project / environment?
The problem never occurs when the backend is running locally. I think the reason for this is: since the server is locally and the latency is minimum, it will always return before Objective-C deallocs the handler - which may not occur if the server is running in a different server.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 18 (9 by maintainers)
You are right - I decided to remove/obfuscate some of the fields/values but I thought that it would not impact our/your guys investigation.
Anyway, I didn’t know that Wireshark supports gRPC/Protobuffer, this is great. I’ll try to monitor one of my sessions using it and also to get some logs from the server. I remember checking logs from Nginx and it was all ok so instead I’ll focus only on the backend itself.
It’s Wireshark.
Does all these logs come from the same grpc call(
/exchange.v1.WfsService/Merge
), looks like only the error one has authority field.NSDebugDescription={"description":"Error received from peer ipv4:x.x.x.:443"}.
The authority field also uses 443, feels like there’s something wrong here.I don’t think the handler is deallocated, if so, you can’t receive responses instead of receiving a RST_STREAM error.
Can you paste your code, I’m curious about how you make a call and what your GRPCCallOptions is.
And also, can you copy and paste the grpc logs for us. You need to set the environment variables
GRPC_TRACE=secure_endpoint
andGRPC_VERBOSITY=DEBUG
in Xcode under theScheme Configurations
(Product -> Scheme -> Edit Scheme -> Run -> Environment Variables), then reproduce the issue and the logs will be in the console.