>
> This is 100% the behavior you want; anything else leads to madness.
> Interceptors inject themselves to the boundary because the application and
> the gRPC library and allow you to do "whatever you want" with the API. This
> produces a layering, and to preserve the layering "who calls who" *must* be
> the *exact* opposite for callbacks as normal method calls.
>
I believe this can make sense in some cases, but I'm not sure that's the
case in general. I believe there are cases where you want the interceptor
to be at the same "logical" place on both paths. For example, a tracing
interceptor wants to be first on the outbound path so create a new span and
wants to be first on the callback path to make it the "active span" again.
As far as I can tell, it is not possible to have this setup with the
current API.
Furthermore, the ServerInterceptor doesn't behave like this, i.e.: the
calls to ServerCall.Listener are in the same order as the calls to
interceptCall. So on that point, perhaps some small documentation updates
would help people figure this out.
> This makes it impossible for an interceptor to do something like:
>>
>> * setup some ThreadLocal state
>> * invoke the next interceptor's method (e.g.: start or onMessage)
>> * teardown ThreadLocal state
>>
>
> How so? Each method call may be on a different thread, so you have to
> setup and teardown the ThreadLocal every method:
>
Hmm, right, my example was incomplete. What I meant to say was that the
same interceptor cannot do this kind of setup for both the outbound and
callback paths.
Again, taking the tracing interceptor as an example, I believe you would
want something like this:
ClientCall interceptCall(...) {
Span span = newSpan();
try(activateSpan(span)) {
return new SimpleForwardingClientCall(next.newCall(...)) {
void start(...) {
try(activateSpan(span)) {
super.start(
new SimpleForwardingClientCallListener(...) {
void onMessage(...) {
try(activateSpan(span)) { super.onMessage(...) }
}
}
}
}
}
}
}
I believe you want the tracing to be setup before all other interceptors on
both paths. For example, so that log statements related to that request are
attached to the same span.
In fact, both the OpenTracing and OpenTelemetry interceptors do exactly
that. The OpenTracing's documentation[1] also mentions that it should be
able to intercept other interceptors, which is not the case if you follow
their suggested setup. I cannot find documentation for the OpenTelemetry
interceptor but it seems to be making a similar assumption...
[1]
https://github.com/opentracing-contrib/java-grpc#integrating-with-other-interceptors
[2]
https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/grpc-1.5/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_5/client/TracingClientInterceptor.java
--
You received this message because you are subscribed to the Google Groups
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/grpc-io/CAFYs7S8wetM74PAOJP_9EJ%3DX_GupoTZ9eXj9tVQMq0EserXz%2BQ%40mail.gmail.com.