(csharp) Alternative to rpcException?

34 views
Skip to first unread message

li yabo

unread,
Oct 10, 2020, 9:02:04 AM10/10/20
to grpc.io
I recently learned rpcException is recommended approach to handle failures:

1. server side can 
     1.1. throw rpcException with status and meta data filled in trailers
     or,
     1.2 set status and trailers to ServerCallContext;

2. client will need to catch rpcException to act upon failure situations, no matter server raised failure via 1.1 or 1.2, because client side library will create rpcException using status and trailers received, and throw.

[Q] for heavy and perf critical APP, exception dispatching is also a perf concern, is it possible to avoid throwing rpcException? (especially on client side). With that, the Application layer code can look into the status code to act as appropriately?

thanks 

Christopher Warrington - MSFT

unread,
Oct 15, 2020, 2:22:02 AM10/15/20
to grpc.io
On Saturday, October 10, 2020 at 6:02:04 AM UTC-7 yabo...@gmail.com wrote:

> for heavy and perf critical APP, exception dispatching is also a perf
> concern, is it possible to avoid throwing rpcException? (especially on
> client side). With that, the Application layer code can look into the
> status code to act as appropriately?

One work around is to lift the error conditions into your application
protocol. Instead of using gRPC's status, always return OK, but have your
messages include success vs. failure information. If you're using Protocol
Buffers, you could model it with a oneof:

message FooResponse {
  oneof r {
    SomeCustomErrorMessage error = 1;
    string good_response = 2;
  }
}

Before committing to this approach, I'd profile it vs. the RpcException
approach. Observing the impact of an exception given that all of this is
going over the network may be hard.

If you can hit your performance goals using RpcExceptions, throwing and
catching is probably a better choice.

--
Christopher Warrington
Microsoft Corp.

Jan Tattermusch

unread,
Oct 19, 2020, 4:29:32 AM10/19/20
to grpc.io
On the client side, the result of a call is represented by a Task<TResponse> (at least in the unary call case which is the most common).
If you think exception dispatching is expensive (possible, but you'd need to benchmark carefully to make sure this is indeed the case, otherwise it's just guesswork), you actually don't have to  call "await call.ResponseAsync" and let the exception be thrown. Instead, you could try just detect if the task has finished (failed or successful) and then inspect "call.GetStatus()" to extract the potential error?
If there is no error, accessing the Task result is going to be immediate (and cheap).

Another solution is what Christopher has described.

li yabo

unread,
Oct 19, 2020, 7:46:08 AM10/19/20
to grpc.io
Thanks a lot for both suggestions.

To implement Jan's idea, seems I need to poll the task object to detect if the ask has finished. Is my understanding right?

Christopher's suggestion doesn't require polling, but I can think of another potential problem is, since the error doesn't reflect in the gRpc statusCode, gRpc retries policy may not work anymore with that error-handling, I will have to handle retries using my custom implementation as well?

Thanks

Reply all
Reply to author
Forward
0 new messages