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

时间:2022-12-30 20:44:08

I'm writing a REST web service using Jersey, CDI 2.0 (Weld 3.0.1.final implementation) and Tomcat. The goal of the webservice is to launch long computation tasks that can be running for several minutes or even hours. The task should be started with HTTP POST request sent to the webservice, however the request must finish immediately and send back the response to the client, while the started task should be doing its job on another thread.

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

I have already solved it by using CDI 2.0 and its Event.fireAsync() method allowing to process events asynchronously. The JAX-RS resource class that handles POST requests fires async event, which is then processed by asynchronous observer method (annotated with @ObservesAsync) in separate @ApplicationScoped CDI bean.

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

The described solution works great. However, I noticed, that when I simultaneously fire several long tasks in async events, only four of them are actually running while the rest is queued. As soon as one of the four running events finishes, the first of queued events starts its processing.

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

So, my questions are:

所以,我的问题是:

  1. How to check how many threads are available for real asynchronous processing of CDI events?
  2. 如何检查有多少线程可用于CDI事件的实际异步处理?

  3. How to check how many events are queued and wait for processing in the asynchronous observer method?
  4. 如何检查排队的事件数并等待异步观察器方法中的处理?

1 个解决方案

#1


2  

For your first question - the default is going to be based on available processors. Something along the lines of Runtime.getRuntime().availableProcessors() + 1. However, what you are after is configuration options I suppose. Here you get to choose, you can either:

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

  • Use Weld configuration and pick from pre-defined options
    • Take a look at configuration part of Weld doc
    • 看看Weld doc的配置部分

    • I would suggest using FIXED_TIMEOUT pool (threads won't linger when not needed), the key for this config is org.jboss.weld.executor.threadPoolType
    • 我建议使用FIXED_TIMEOUT池(线程不会在不需要时逗留),这个配置的关键是org.jboss.weld.executor.threadPoolType

    • You can set desired amount of threads using the key org.jboss.weld.executor.threadPoolSize
    • 您可以使用密钥org.jboss.weld.executor.threadPoolSize设置所需的线程数

    • Check chapter 19.1 on how to pass config options to Weld
    • 查看有关如何将配置选项传递给Weld的第19.1章

  • 使用Weld配置并从预定义的选项中选择看看Weld doc的配置部分我建议使用FIXED_TIMEOUT池(线程不会在不需要时延迟),此配置的密钥是org.jboss.weld.executor。 threadPoolType您可以使用密钥org.jboss.weld.executor.threadPoolSize设置所需的线程数量检查有关如何将配置选项传递给Weld的第19.1章

  • Define your own Executor and fire async events with that using the NotificationOptions
  • 使用NotificationOptions定义您自己的Executor并触发异步事件

  • (OVERKILL) Implement your own ExecutorServices, part of Weld SPI
  • (OVERKILL)实现自己的ExecutorServices,这是Weld SPI的一部分

For your second question - I'll have to disappoint you here. There is no way of achieving this within Weld yet. Feel free to create a WELD Jira issue and you might see it in the future.

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

#1


2  

For your first question - the default is going to be based on available processors. Something along the lines of Runtime.getRuntime().availableProcessors() + 1. However, what you are after is configuration options I suppose. Here you get to choose, you can either:

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

  • Use Weld configuration and pick from pre-defined options
    • Take a look at configuration part of Weld doc
    • 看看Weld doc的配置部分

    • I would suggest using FIXED_TIMEOUT pool (threads won't linger when not needed), the key for this config is org.jboss.weld.executor.threadPoolType
    • 我建议使用FIXED_TIMEOUT池(线程不会在不需要时逗留),这个配置的关键是org.jboss.weld.executor.threadPoolType

    • You can set desired amount of threads using the key org.jboss.weld.executor.threadPoolSize
    • 您可以使用密钥org.jboss.weld.executor.threadPoolSize设置所需的线程数

    • Check chapter 19.1 on how to pass config options to Weld
    • 查看有关如何将配置选项传递给Weld的第19.1章

  • 使用Weld配置并从预定义的选项中选择看看Weld doc的配置部分我建议使用FIXED_TIMEOUT池(线程不会在不需要时延迟),此配置的密钥是org.jboss.weld.executor。 threadPoolType您可以使用密钥org.jboss.weld.executor.threadPoolSize设置所需的线程数量检查有关如何将配置选项传递给Weld的第19.1章

  • Define your own Executor and fire async events with that using the NotificationOptions
  • 使用NotificationOptions定义您自己的Executor并触发异步事件

  • (OVERKILL) Implement your own ExecutorServices, part of Weld SPI
  • (OVERKILL)实现自己的ExecutorServices,这是Weld SPI的一部分

For your second question - I'll have to disappoint you here. There is no way of achieving this within Weld yet. Feel free to create a WELD Jira issue and you might see it in the future.

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