grpc-dotnet
grpc-dotnet copied to clipboard
When to call Resolver.Refresh?
I was recently experimenting with use of a custom resolver for a use case I have where our grpc services can change addresses as they are stopped/started. We currently have a bunch of try/catch/reresolve/retry code littered around our clients because of this, and I was hoping this feature might tidy this up and better centralize the logic.
My initial attempt at implementing a custom resolver with the default load balancing strategy worked almost exactly like I wanted. The only problem is that currently the load balancer seems to be responsible for calling Resolver.Refresh
unless you kick off a periodic refresh via a timer or something like that. That's fine except that the PickFirstBalancer
calls RefreshResolver when the subchannel moves to the Idle
state. This was a little surprising to me since I thought it would have made more sense to delay this until moving back to the Connecting
state. Because of this, the custom resolver doesn't really help me unless I also:
- Write a custom load balancer so I can refresh the address when reconnecting the channel instead of when the channel goes idle. This is doable but seems like a waste since I basically end up forking the implementation of the
PickFirstBalancer
. I couldn't find any way to customize the behavior, and the class isinternal
andsealed
so I can't derive from it or instantiate it so I can wrap it and forward calls to it. - Add a timer that continuously runs and makes refresh calls at some interval similar to
DnsResolver
. This isn't ideal since it's difficult to pick an interval that doesn't seem like it's flooding the resolution server unnecessarily and yet seems responsive from the client side.
So I guess the question is if there is a better way to about this that I'm not seeing? Is there a reason refresh is called from Idle
rather than Connecting
? I'm sure there must be, but it's not immediately obvious to me. I'm not sure if moving the call to Idle
might present challenges with not resolving twice upon initial connection for the channel as opposed to reconnecting after going idle.