gpt4 book ai didi

java - 更改从不同线程提交到 ManagedExecutorService 的 Runnable 中的 CDI sessionscoped bean 会引发 ContextNotActiveException

转载 作者:行者123 更新时间:2023-12-01 22:35:31 24 4
gpt4 key购买 nike

我在 REST 服务中调用了以下方法,需要立即返回:

@Inject
private ScheduleManager scheduleManager;

@Resource(name = "DefaultManagedExecutorService")
ManagedExecutorService executor;

public String solveSchedule(@PathParam("conferenceId") Long conferenceId) {
executor.submit(new SolverCallable());
return "Solved started.";
}

它提交这个内部类以在另一个线程上执行

private class SolverCallable implements Runnable {

public void run() {
Schedule bestSchedule = ...; // do some long computation
scheduleManager.setSchedule(bestSchedule); // throws ContextNotActiveException
}

}

如何使用长计算的结果更改 Runnable 中的 session 作用域 bean?

最佳答案

你不能。即使您传递了引用,该引用也会丢失,因为您获得的只是代理。代理旨在查看 Activity 线程并在这些线程上执行工作。当它到达托管执行程序时,该线程不是原始 HTTP session 的一部分,因此,您会收到 ContextNotActiveException

从技术上讲,JAX-RS 并不能很好地理解 HTTP session ,规范中没有 JAX-RS 资源参与 HTTP session 的实际要求。

我向人们推荐的最常见的解决方法是使用一些集中位置来存储这些类型的大型结果,并从那里读取 session 范围的对象。让执行者也与该组件对话。这可能就像一个与 HTTP session ID 无关的 HashMap 一样简单。

要获取 session ID,只需调用 HttpSession.getId()。您还可以通过使用 @SessionScoped bean 之一中的 @PreDestroy 方法来调用中心点并销毁引用来销毁 map 引用。

就线程而言,除了能够从 session 作用域 bean 中注入(inject)对可运行对象的引用(或使可运行对象成为 session 作用域 bean)并告诉它之外,我想不出任何方法来终止它。它从那里停止线程。

@SessionScoped
public class SessionBean implements Runnable,Serializable {

private HttpSession httpSession;
@PostConstruct
public void init() {
httpSession = CDI.current().select(HttpSession.class).get();
// register the session
}
@Override
public void run() {

}

@PreDestroy
public void unregister() {
// unregister the session
// kill the thread.
}
}

关于java - 更改从不同线程提交到 ManagedExecutorService 的 Runnable 中的 CDI sessionscoped bean 会引发 ContextNotActiveException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26934461/

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