gpt4 book ai didi

java - 在 grpc 拦截器中使用 ThreadLocal 的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-04 12:25:27 54 4
gpt4 key购买 nike

我们有一个 gPRC 服务,它需要在类的 ThreadLocal 变量中设置身份验证/身份信息,才能正确调用另一个服务。 gPRC 服务从请求中获取身份验证/身份信息,所以我想使用拦截器。

首先,我有一些如下所示的代码。

public class ImpersonationInterceptor {
public <ReqT, RespT> interceptCall(
ServerCall<ReqT, RespT> serverCall, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
Principal principal = ... // get the identify from the request

AuthContext.setPrincipal(principal); // underneath it uses a ThreadLocal.

return next.startCall(
new SimpleForwardingServerCall<>(call) {
public void close(Status status, Metadata trailers) {
AuthContext.setPrincipal(null); // clear the identity
}
}
)
}
}

问题。
  • 服务方法本身的执行可能不会在同一个线程上执行拦截器,对吗?
  • 如果为真,上面的方法是行不通的,那么问题是,在 gRPC 世界中设置 ThreadLocal 变量的规范方法是什么?我知道 gRPC 从 0.12 开始就支持 Context,但就我而言,我必须使用 AuthContext 的 ThreadLocal 机制。

  • 首先十分感谢。

    最佳答案

    对于此类上下文信息,您必须非常小心使用 ThreadLocals,因为您不想意外地为客户端使用错误的标识。

    gRPC 的每个回调都可以发生在不同的线程上,多个 RPC 的回调可以发生在同一个线程上。

    你需要遵循这样的模式 Contexts.interceptCall() .您必须在每次通话后设置/取消设置:

    public class ImpersonationInterceptor {
    public <ReqT, RespT> interceptCall(
    ServerCall<ReqT, RespT> serverCall, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
    Principal principal = ...;
    AuthContext.setPrincipal(principal);
    try {
    return new WrappingListener<>(next.startCall(call, headers), principal);
    } finally {
    AuthContext.clearPrincipal();
    }
    }

    private static class WrappingListener<ReqT> extends
    ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT> {
    private final Principal principal;

    public WrappingListener(ServerCall.Listener<ReqT> delegate, Principal principal) {
    super(delegate);
    this.principal = principal;
    }

    @Override
    public void onMessage(ReqT message) {
    AuthContext.setPrincipal(principal);
    try {
    super.onMessage(message);
    } finally {
    AuthContext.clearPrincipal();
    }
    }
    ... repeat for each method
    }
    }

    关于java - 在 grpc 拦截器中使用 ThreadLocal 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56836544/

    54 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com