如何在请求开始时创建Context对象的条目,并在请求结束时检索它?

时间:2018-08-02 21:55:27

标签: java grpc grpc-java

(免责声明:我正在涉足grpc)

我有一个要与每个请求关联的对象,initialize在请求开始时将其关联,并在请求完成后close将其关联。

当前,我通过使用两个ServerInterceptors实现这一目标,第一个将对象填充到上下文中,第二个拦截onReadyonComplete分别初始化和关闭对象。

PopulateObjectServerInterceptor

public class FooBarInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
    FooBar foobar = FooBar.create(foo, bar);
    Context ctx = Context.current().withValue(Constants.FOO_BAR, foobar);

    return Contexts.interceptCall(ctx, call, headers, next);
}

RequestLifecycleInterceptor

public class FooBarLifecycleServerInterceptor implements ServerInterceptor {
    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
                                                                 Metadata headers,
                                                                 ServerCallHandler<ReqT, RespT> next) {

        final ServerCall.Listener<ReqT> original = next.startCall(call, headers);

        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(original) {
            @Override
            public void onReady() {
                FooBar foobar = (FooBar) Context.key("foobarname").get();
                foobar.initialize()
                super.onReady();
            }

            @Override
            public void onMessage(final ReqT message) {
                FooBar foo = (FooBar) Context.key("foobar").get();
                foobar.someaction()
                super.onMessage(message);
            }

            @Override
            public void onComplete() {
                FooBar foo = (FooBar) Context.key("foobar").get();
                foobar.close()
                super.onComplete();
            }
        }
    } 
}

这是正确/推荐的方式吗?我想知道我是否可以仅使用一个拦截器就能做到这一点...

1 个答案:

答案 0 :(得分:0)

您在做什么看起来不错。另一种方法是在FooBarLifecycleServerInterceptor中创建对象,并首先避免使用Context,但是示例中可能未说明其他一些要求。

注意: onReady may not do what you think it does。如果您的想法是在每次服务器调用开始时调用Initialize,我认为您应该在发生呼叫拦截时就执行此操作。

将调用onCompleteonCancel中的一个,因此在调用close()时也应调用onCancel