There are many different examples for making gRPC interceptor async
, but all of them are post-processing interceptors. For example
public class ErrorHandlerInterceptor : Interceptor
{
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
var call = continuation(request, context);
return new AsyncUnaryCall<TResponse>(
HandleResponse(call.ResponseAsync),
call.ResponseHeadersAsync,
call.GetStatus,
call.GetTrailers,
call.Dispose);
}
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> inner)
{
try
{
return await inner;
}
catch (Exception ex)
{
throw new InvalidOperationException("Custom error", ex);
}
}
}
In this case I can only do different actions which cannot transform current call - I can't modify context
via this call.
but what if I want to some actions before call? For example, I want to have pre-propcessing method call fully async like this:
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
var newContext = await PreProcessing(context);
var call = continuation(request, newContext);
return new AsyncUnaryCall<TResponse>(
HandleResponse(call.ResponseAsync),
call.ResponseHeadersAsync,
call.GetStatus,
call.GetTrailers,
call.Dispose);
}
private async Task<ClientInterceptorContext<TRequest, TResponse> context> PreProcessing(ClientInterceptorContext<TRequest, TResponse> oldContext)
{
//do some async calls
return new ClientInterceptorContext<TRequest, TResponse>(oldContext.Method, oldContext.Host, oldContext.Options.WithHeaders(metaData))
}
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> inner)
{
try
{
return await inner;
}
catch (Exception ex)
{
throw new InvalidOperationException("Custom error", ex);
}
}
}
Is it possible? I've tried to realize this with ContinueWith
, but failed... (((