GRPC-使用ContextPropagatingExecutorService和CurentConextExecutor
由于GRPC在新线程上进行服务调用,并且GRPC上下文是线程本地的,我如何传播此GRPC上下文?我发现可以使用Conext.currentContextExecutor()和ConextPropagatingExecutorService,但我没有找到足够的资源或示例来支持这两个选项。有人能帮助实施这些吗?
解决方案
客户端侦听器不应更改应用程序看到的上下文实例。无论是使用阻塞、异步还是将来的存根,以及阻塞API将无法更改当前上下文,上下文行为都不应真正更改。
虽然拦截器可以自由地修改上下文中预先存在的(可变)值,但通常不需要这样做。通常,在每个RPC中创建一个新的拦截器实例并直接与拦截器通信,或通过自定义的CallOption进行通信更容易。如果您只有一个需要访问响应头的调用站点,那么MetadataUtils.newCaptureMetadataInterceptor()
是获取元数据的一种方便(尽管迂回)的方法。它是为测试而设计的,但适用于测试情况之外的小规模使用。
AtomicReference<Metadata> headers = new AtomicReference<>();
AtomicReference<Metadata> trailers = new AtomicReference<>();
// Using blocking for simplicity, but applies equally to futures
stub.withInterceptors(MetadataUtils.newCaptureMetadataInterceptor(headers, trailers))
.someRpc();
Metadata headersSeen = headers.get();
如果需要从多个调用点访问相同的标头,最好创建一个执行所需操作的自定义侦听器。
CustomInterceptor interceptor = new CustomInterceptor();
stub.withInterceptors(interceptor)
.someRpc();
... = interceptor.getWhateverValue();
这是在演示一个通用用例。特定实例通常可以进一步调整接口,使其更方便、更自然。
相关文章