[英]ThreadLocals on GraphQL-Java
我在 GraphQL 上公开了一个旧的 Web 应用程序,但是这个 Web 应用程序使用了 Threadlocals(以及其他 Apache-Shiro)。
由于 GraphQL-java 似乎使用fork-join pool
进行并发,我担心需要走多远才能确保我的 ThreadLocals 仍然可以正常工作并安全地工作。
阅读文档和来源,似乎并发的很大一部分是由返回CompletableFuture
的 DataFetchers 实现的,我无法确定这是否是唯一的并发来源(我认为不是)以及DataFetchers
本身是否是从fork-join pool
那么将我的DataFetcher
包装在一个设置和清除 ThreadLocals 的委托中是否安全? 或者这是否仍然存在被抢占并继续在fork-join pool
另一个线程上的风险,例如:
static class WrappedDataFetcher implements DataFetcher<Object> {
private DataFetcher<?> realDataFetcher;
WrappedDataFetcher(DataFetcher<?> realDataFetcher) {
this.realDataFetcher = realDataFetcher;
}
@Override
public Object get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception {
try {
setThreadLocalsFromRequestOrContext(dataFetchingEnvironment);
return realDataFetcher.get(dataFetchingEnvironment);
} finally {
clearTreadLocals();
}
}
}
或者我是否需要在线程池中显式运行我的 DataFetchers,例如:
static class WrappedDataFetcherThreadPool implements DataFetcher<Object> {
private DataFetcher<?> wrappedDataFetcher;
private ThreadPoolExecutor executor;
WrappedDataFetcherThreadPool(DataFetcher<?> realDataFetcher, ThreadPoolExecutor executor) {
// Wrap in Wrapper from previous example to ensure threadlocals in the executor
this.wrappedDataFetcher = new WrappedDataFetcher(realDataFetcher);
this.executor = executor;
}
@Override
public Object get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception {
Future<?> future = executor.submit(() -> wrappedDataFetcher.get(dataFetchingEnvironment));
return future.get(); //for simplicity / clarity of the question
}
}
我认为第二个解决了我的问题,但感觉有点矫枉过正,我担心性能。 但我认为第一个有抢占的风险。
如果有更好的方法来处理这个问题,我也很乐意听到。
注意:这不是关于 GraphQL 的异步性质(我也希望利用它),而是关于使用带有treadLocals 的多个请求可能会由于fork-join pool
而在请求之间混淆的可能副作用
据我所知,graphql-java 不使用自己的线程池,而是依赖于应用程序。 它使用未来回调实现它的方式。 假设这是应用程序的当前状态。
具有线程本地存储 TLS_1 的线程 T_1 执行数据提取器 DF_1。
Graphql-java 引擎将同步回调附加到 DF_1 返回的未来。 如果未返回未来,它将结果包装在已完成的未来中,然后附加同步回调。 由于回调是同步的,完成未来的线程运行回调。 如果除 T_1 之外的任何其他线程完成未来,则 TLS_1 将丢失(除非它被复制到正在执行的线程)。 一个例子是一个非阻塞的 HTTP I/O 库,它使用一个 I/O 线程来完成未来的响应。
这是作者对 graphql-java 库中的线程行为进行了更多评论的链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.