Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GRPC Java pass data from server interceptor to rpc service call

Tags:

java

grpc

We are using Java GRPC for one of our internal services and we have a server side interceptor that we use to grab information from the headers and set them up in a logging context that that uses a ThreadLocal internally.

So in our interceptor we do something similar to this:

LogMessageBuilder.setServiceName("some-service");

    final String someHeaderWeWant = headers.get(HEADER_KEY);

    final LoggerContext.Builder loggingContextBuilder = new LoggerContext.Builder()
        .someFieldFromHeaders(someHeaderWeWant);
LoggerContext.setContext(loggingContextBuilder.build());

Then in our service call we access it like this:

LoggingContext loggingContext = LoggingContext.getCurrent()

However the current context is null some of the time.

We then tried to use the GRPC Context class like below:

LogMessageBuilder.setServiceName("some-service");

        final String someHeaderWeWant = headers.get(HEADER_KEY);

        final LoggerContext.Builder loggingContextBuilder = new LoggerContext.Builder()
            .someFieldFromHeaders(someHeaderWeWant);
    Context.current().withValue(LOGGING_CONTEXT_KEY, loggingContextBuilder.build()).attach()

Then accessing it in the service call like:

LoggingContext context = LOGGING_CONTEXT_KEY.get(Context.current())

However that is also sometimes null and if I print out the memory addresses it appears that early on the context is always the ROOT context regardless of me attaching in the interceptor, but after a few calls the contexts are correct and the logger data is there like it should.

So if anyone has any ideas or better ways to propagate data from an interceptor to the service call I would love to hear it.

like image 264
twreid Avatar asked Jan 20 '16 16:01

twreid


1 Answers

Each callback can be called on a different thread, so the thread-local has to be set for each callback. It seems you may accidentally be getting Contexts intended for other RPCs.

grpc-java 0.12.0 should be released this week. Context has been partially integrated in 0.12.0, and we also added Contexts.interceptCall() which is exactly what you need: it attaches and detaches the context for each callback.

In 0.12.0, you should now see new contexts being created for each server call (instead of ROOT) and contexts propagated from client calls to StreamObserver callbacks.

As another note, unlike ThreadLocal Context is intended to be tightly scoped: after attach(), you should generally have a try-finally to detach().

like image 91
Eric Anderson Avatar answered Oct 23 '22 20:10

Eric Anderson