question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Grpc Client - Interceptor - only created once (singleton)

See original GitHub issue

I’ve created an interceptor for gRPC clients like it’s described here: https://docs.microsoft.com/en-us/aspnet/core/grpc/clientfactory?view=aspnetcore-3.1 and it’s working fine.

However I want that the inceptor (in my sample below it’s called MyClientInterceptor) is created for each request, at the moment it’s created on the first call and all subsequent calls using the same instance of MyClientInterceptor.

I also registered MyClientIncepter in Unity 5 (I use Microsoft Unity as IOC) as transient, but that doesn’t help because .AddInterceptor() adds the interceptor to a collection instead of resolving it for each request.

Is there some way I can archive this? I want/need to do this because I have to resolve some other instances from the current ioc-container (the child container that’s automatically created for each request).

I’ve registered the interceptor like this (there are also some overloads for interceptor but the beaviour is the same):

services
    .AddGrpcClient<Greeter.GreeterClient>(o =>
    {
        o.Address = new Uri("https://localhost:5001");
    })
    .AddInterceptor<MyClientInterceptor>();

br

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
abe545commented, Jan 4, 2021

Hi @JamesNK - just wanted to add Namely’s upvote for making the interceptors scoped to individual requests. We use them for a few things that use information from the current request:

  1. Forward additional headers that aren’t handled by the default implementation
  2. Automatically inject a service authorization token if not user initiated for specific endpoints
  3. Emit metrics for problematic patterns (for instance, detect if an RPC is happening in the context of an open DB transaction)
  4. Distributed tracing

Most of the above are entirely possible if the interceptors are singletons if the service is running in the context of asp .net (whether grpc or mvc) using the IHttpContextAccessor. However, we have applications that are based on kafka handlers, and we still want to support things like forwarding request headers from the kafka message. So we’d essentially have to implement the same pattern for accessing the current request, instead of what we do now - inject the current request information using DI inside a request scope. This would be a fair amount of code to change for us, and I’d like to avoid doing so if at all possible.

I’ve been able to work around this by registering my own implementation of the GrpcClientFactory as transient, while creating and holding a reference to the GrpcChannel in a singleton GrpcChannelFactory. We’ve been hesitant to widely deploy this, as we’re not 100% sure if we’re introducing some subtle bug with the channel; but our c-based implementation just kept the channels as singletons, so I’m fairly confident it will not be worse.

2reactions
JamesNKcommented, Jun 5, 2020

are singletons the only supported interceptor on the client?

Yes.

I’ll see whether I can improve this in future versions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bypass gRPC interceptor for specific endpoint
The only option that I could find is to define a new ServerInterceptor that retrieves the endpoint name through an io.grpc.Listener#onMessage ...
Read more >
gRPC interceptors on .NET
Interceptors can be implemented for both gRPC servers and clients by creating a class that inherits from the Interceptor type:.
Read more >
Implementing a gRPC Service
gRPC server interceptors let you perform logic, such as authentication, before your service is invoked. You can implement a gRPC server interceptor by...
Read more >
Injection scopes | NestJS - A progressive Node.js framework
Singleton scope is used by default. REQUEST, A new instance of the provider is created exclusively for each incoming request. The instance is...
Read more >
Micronaut gRPC
This project allows building gRPC servers and clients with Micronaut. ... To get started you need first create a Micronaut project.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found