CDI 2.0:如何检查使用Event.fireAsync()触发的异步事件数可以同时运行

时间:2017-11-22 18:52:07

标签: java tomcat cdi weld cdi-2.0

我正在使用Jersey,CDI 2.0(Weld 3.0.1.final实现)和Tomcat编写REST Web服务。 Web服务的目标是启动可以运行几分钟甚至几小时的长计算任务。应该使用发送到Web服务的HTTP POST请求启动任务,但是请求必须立即完成并将响应发送回客户端,而启动的任务应该在另一个线程上执行其作业。

我已经通过使用CDI 2.0及其Event.fireAsync()方法解决了这个问题,允许异步处理事件。处理POST请求的JAX-RS资源类触发异步事件,然后由异步观察者方法(用@ObservesAsync注释)在单独的@ApplicationScoped CDI bean中处理。

所描述的解决方案效果很好。但是,我注意到,当我同时在异步事件中触发几个长任务时,其中只有四个实际上正在运行而其余的排队。只要四个运行事件中的一个结束,第一个排队事件就会开始处理。

所以,我的问题是:

  1. 如何检查有多少线程可用于CDI事件的实际异步处理?
  2. 如何检查排队的事件数并等待异步观察者方法中的处理?

1 个答案:

答案 0 :(得分:2)

对于您的第一个问题 - 默认值将基于可用的处理器。类似Runtime.getRuntime().availableProcessors() + 1的内容。 但是,你想要的是配置选项。在这里你可以选择,你可以:

  • 使用焊接配置并从预定义的选项中选择
    • 查看configuration part of Weld doc
    • 我建议使用FIXED_TIMEOUT池(线程在不需要时不会延迟),此配置的密钥为org.jboss.weld.executor.threadPoolType
    • 您可以使用键org.jboss.weld.executor.threadPoolSize
    • 设置所需的线程数量
    • 检查chapter 19.1如何将配置选项传递给Weld
  • 使用NotificationOptions
  • 定义您自己的Executor并触发异步事件
  • OVERKILL )实施您自己的ExecutorServices,这是Weld SPI的一部分

对于你的第二个问题 - 我在这里不得不让你失望。目前还没有办法在Weld内实现这一目标。欢迎create a WELD Jira issue,您可能会在将来看到它。