using async/await with gRPC Interceptors problem

141 views Asked by At

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... (((

0

There are 0 answers