Java gRPC - conditional forwarding server interceptor

1,328 views
Skip to first unread message

matt.m...@lucidworks.com

unread,
Dec 8, 2017, 9:26:51 AM12/8/17
to grpc.io
Hi,

I'm trying to find examples for how I can achieve a conditional forwarding interceptor, on the server. My gRPC instances can have stateful information attached to them (stored in Zookeeper), mainly the ID of a Job currently running on a node. I can get a node's host/port based on the Job ID from a little service discovery utility ("getAddressByJobId(jobId)" etc.), and so I'd like requests for getting a Job's status to be routed to the correct node based on the requested Job ID. If there is no node hosting the Job, then I don't want any forwarding at all, and instead just call the current node's "getJobStatus" method. In the case where the interceptor does forward, I can set a "forwarded" header so that when the correct node does get the request, the interceptor won't continue to forward/redirect.

I can get simple interceptor examples to work fine - but am struggling to get this specific flow to work. Anyone have something like this available? If not, could someone be kind enough to show an example of how I might do this?

Thanks,
- Matt

Kun Zhang

unread,
Dec 12, 2017, 7:31:43 PM12/12/17
to grpc.io
I am not sure I understand what you are trying to do. Are you trying to create a proxy? A proxy wouldn't need server interceptor. Instead, you can use a dynamic fallback handler registery. It can handle RPCs for arbitrary method names, and you can do the forwarding there.

Eric Anderson

unread,
Dec 15, 2017, 11:00:58 AM12/15/17
to Matt Mitchell, grpc.io
On Fri, Dec 8, 2017 at 6:26 AM, <matt.m...@lucidworks.com> wrote:
I'm trying to find examples for how I can achieve a conditional forwarding interceptor, on the server.

The conditional aspect of an interceptor should be trivial, as you should just use an if in your interceptor.

"Forwarding" here sounds like you want to forward to another server (vs forwarding in-process to a different object). In general, this case seems simple enough you should just write the code as a normal service, and have the service issue a gRPC request to the correct backend. No fancy business, other than propagating the "no forwarding" bit to your service via Contexts.interceptCall(...).

The only time I'd have expected to use an interceptor here is if you were wanting to do this logic on client-side using a client interceptor.

I did write the beginnings of an example (it's not merged, but functional) that does "forwarding" in the proxy sense. But it wouldn't be easy to use in your case since you want to parse/process the request message to determine where to forward to. Generic proxies would tend to use only Metadata for routing. Service-specific proxies should generally just write a service that behaves how they want.

matt.m...@lucidworks.com

unread,
Dec 19, 2017, 9:57:21 PM12/19/17
to grpc.io
Thanks everyone. We ended up going with the last suggestion, which was to have this all be handled in a service. Working great.

And btw, we're also using the Proxy you created, Eric. Slightly different use case for us (no need to inspect the metadata) and is working great. Do you plan on having this go into gRPC eventually?

Thanks,
Matt

prod...@google.com

unread,
Jan 10, 2018, 1:54:50 PM1/10/18
to grpc.io
I have a project with a nearly identical use case to yours. It sounds like you used Zookeeper to implement your centralized state management and provide your forwarding table. I was curious if there were any other broadcast-type mechanisms available within the gRPC framework to avoid the need for a centralized state store. Ideally, each service node would broadcast the jobs they were capable of servicing to other nodes and each node would maintain knowledge of the others in-memory.

Anyone aware of something like that?
Reply all
Reply to author
Forward
0 new messages