I don't understand what you're asking for here.
Not sure what "redelivery delay for the whole topic" means. Or "message thrashing" in this context.
More description would be beneficial.
Suppose I have a single message in a topic and that topic has a redelivery delay of 5 seconds.
An MDB receives the message and throws an EJBException so the message will be redelivered. That message will be delivered every 5 seconds.
Now, suppose that I have two messages in the topic. The first message is received, rolled back, and immediately followed by the second message (maxSession=1 and maxMessages=1). n number of messages will come in rapid succession, and that is what I mean by message thrashing.
The behavior I want is for the second message to be delivered 5 seconds after the first message is rolled back. So, in essence, I want the redelivery delay to take place for the entire topic.
You probably want only allow a single consumer, and you probably want to set slow consumer at the connection factory used by the topic.
Change the MDB to only use a single instance, and don't have the client buffering messages. It seems you don't want buffering at the client side, so you could disable that.
The MDB uses a single instance. Setting consumer-window-size has no effect on the behavior.
Testing with 2.1.0.Final using the stand-alone, non-clustered server
Enqueuing 2 messages into a queue where a message listener always rolls back, produces deliveries with the following times:
[17:27:58:338] received message: Red Message
[17:27:58:342] received message: Green Message
[17:28:08:342] received message: Red Message
[17:28:08:348] received message: Green Message
[17:28:18:344] received message: Red Message
[17:28:18:351] received message: Green Message
[17:28:28:347] received message: Red Message
[17:28:28:365] received message: Green Message
[17:28:38:349] received message: Red Message
[17:28:38:367] received message: Green Message
Since consumer-window-size is set to 0, I would expect to only see a single message attempt to deliver every 10 seconds.
Are my expectations incorrect?
Why you don't post your code.
Perhaps you misconfigured something on the Address-settings. It would really easy our communication with you.
Even if it is a bug in our side. As you have your code.. we always ask to a testcase replicating the issue as you see it:
Sure, I didn't want to jump to a bug report because I honestly don't know what the expected behavior is here.
To reproduce this:
Edit hornetq-configuration.xml, add the following to <address-setting match="#">
Edit hornetq-jms.xml, add the following to <connection-factory name="NettyConnectionFactory">
Unpack the attached archive and execute the run.sh script:
./run.sh Enqueue 127.0.0.1 # enqueues 2 messages
./run.sh Receive 127.0.0.1 # listen for messages
The Receive class will rollback all messages it receives, so you should see each message delivered 5 times before they go to DLQ.
consumer-window-test.tar.gz 1.4 MB
I don't see an issue here...
The message will be redelivery in the appropriate redelivery time and the next message is already available for redelivery.
you want the whole delivery blocked while the message is not redelivered?
I would keep retrying inside the consumer method until you are done with the message.
Or simply don't use redelivery-timeout. The message will always come at the right order on that case.
Retrying inside the consumer becomes a problem when you are using transacted messages.
The consumer may not be able to guarantee that it can process a mesasge within the configured transaction timeout.
If your consumer relies on some external service in order to successfully process messages, dealing with the availability of that service can be a difficult problem.
We were looking at redelivery-delay as a potential solution to keep the consumer from overloading an external service that is either unresponsive or unavailable.
Based on your explaination that's not a viable solution, as the redelivery-delay applies to each message and the consumer will continue to receive all the messages available for delivery.
A lot of my confusion is based on the fact that JBossMQ operates differently in this regard, thanks for looking at this.
I don't know how JBoss MQ used to operate. HornetQ is a different product:
Redelivery delay is a "value added feature" of HornetQ that operates as follows:
- The message will be resent in "N Seconds" and the message would be back to the queue at the time redelivery happened.
so, that means if you need guaranteed ordering in the way you defined, you can't use redelivery delay. I've tried the same test you produced, and the message was redelivered correctly when there was no redelivery delay.
What you want is a different feature:
"Delayed block on the queue" (blocking the queue for N Seconds after a rollback).
You could open the JIRA producing some evidence of your use case and we can think about it.
I don't know if you really need the feature, but you would be able to achieve what you want if you waited a few seconds if the message is being redelivered.
public void onMessage(Message x)
Message was edited by: Clebert Suconic
public void onMessage(Message x)
Is this solution still viable when using a MDB?
The EJB 3.0 spec indicates it is not (see section 21.1.2), but JBoss may allow it.
If it's not, that may be reason enough for the feature request.
I don't see any restriction on Thread.currentThread().sleep(X)
That section forbides managing threads. (that means starting, stopping or changing priorities). Just getting the currentThread() to perform a sleep shouldn't be a problem on any application server. (In my opinion at least)
Anyway... I feel this is an edgy case, but you should definitely request the feature. Can you open the JIRA please?