CDI 2.0: How to check how many asynchronous events fired with Event.fireAsync() can run simultaneously

841 views Asked by At

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.

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.

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. How to check how many events are queued and wait for processing in the asynchronous observer method?
1

There are 1 answers

0
Siliarus On BEST ANSWER

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:

  • Use Weld configuration and pick from pre-defined options
    • Take a look at configuration part of 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
    • You can set desired amount of threads using the key org.jboss.weld.executor.threadPoolSize
    • Check chapter 19.1 on how to pass config options to Weld
  • Define your own Executor and fire async events with that using the NotificationOptions
  • (OVERKILL) Implement your own ExecutorServices, part of 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.