2

In the JMS world you can easily define the degree of concurrency by tuning the maxSession property in message-driven beans (MDB). Now Quarkus obviously doesn't have MDBs but how do you achieve the same level of concurrency tuning?

I had a look at the guide (Quarkus - Using JMS) but all the consumer does in the example is picking up messages using an infinite loop. I think that's a really bad example. I understand the syntax but the way it consumes messages looks like a busy waiting to me.

So I thought maybe I was missing the point and reactive messaging was the way to go in order to handle more messages more efficiently. I had a look at the guide Quarkus - Using AMPQ with Reactive messaging however once again it doesn't say anything about concurrency of consumers. In this last example the Price Generator bean is an application-scoped bean consuming messages from an Artemis broker using reactive messaging annotations, that's cool but what about concurrency?

If I want an incoming-channel (or a JMS queue) to be consumed faster than others then how do I achieve that on Quarkus? Can you share an example please?

  • Can you define "busy waiting" and also point out what specifically "looks like busy waiting" to you on the [using JMS](https://quarkus.io/guides/jms#the-price-consumer) example? – Justin Bertram Jun 05 '20 at 12:06
  • Look at the PriceConsumer class. It's an @ApplicationScoped that implements Runnable, somehow it obtains a single-thread scheduler and schedule itself as a runnable task. In its run() method then it has a while (true) {... to consume the message. It's confusing. – Marco Del Percio Jun 05 '20 at 14:50
  • I did look at the `PriceConsumer` class. It "obtains" a single-thread scheduler simply by invoking `Executors.newSingleThreadExecutor()` when it's created. The `while (true)` contains an invocation of `javax.jms.JMSConsumer.receive()` which *blocks* (as described in [the JavaDoc](https://docs.oracle.com/javaee/7/api/javax/jms/JMSConsumer.html#receive--)). There's no busy waiting. The `while (true)` exists so that the consumer will *keep consuming* messages until it receives a `null` message. I don't understand what's confusing about that. – Justin Bertram Jun 05 '20 at 15:04
  • My question in the topic was how to achieve a queue consumed by multiple threads? Also why is it using Executors rather than ManagedExecutorService? – Marco Del Percio Jun 08 '20 at 06:46
  • 1
    In the JMS case if you want multiple consumers then you would create multiple consumers. If they are to be used from different threads each should be on their own JMSContext also (which can be created either on the same underlying connection by calling createContext on an existing JMSContext, or on their own connection from the connection factory as shown). If you dont want to call receive on the consumers you could alternatively set a MessageListener and have messages delivered to onMessage on the JMSContext delivery thread. – Robbie Gemmell Jun 08 '20 at 12:11
  • I understand your main question is related to consumer concurrency. I don't have an answer for that, but I thought I could help clarify some other aspects of your question. That said, in the JMS example you could presumably just spin up more threads from the executor to increase consumer concurrency. – Justin Bertram Jun 08 '20 at 13:57
  • RobbieGemmell could you please clarify with an example? How do I create multiple consumers? In that example the consumer is an @ApplicationScoped bean, are you suggesting to create more of those? – Marco Del Percio Jun 09 '20 at 07:45

0 Answers0