Issues with message delivery
timfox Oct 5, 2005 1:32 PMWe have a set of fairly major issues in the way message delivery and redelivery is currently implemented in JBoss Messaging.
I have captured the issues in a set of tests, TransactedSessionTest, testRedel 1-6
They are probably the best description of the problems.
One of the issues is a follows:
1. Send 3 messages m1, m2, m3 in a transacted session
2. Receive m1 only in the same session using consumer1
3. commit the session
4. Try and receive m2, m3 in the same session using new consumer2.
Expected result is that m2 and m3 are received, in fact they're not.
This is because messages m2 and m3 are left sitting in the client side callbackhandler buffer.
When the tx commits, deliveries are left hanging in the corresponding severconsumerdelegate.
All the other issues are related but subtly different.
In order to resolve this, we need to do something like the following:
On commit:
1. Process acks and sends as normal
2. Any outstanding deliveries remaining any any serverconsumerdelegates enlisted in the tx represent messages that were either received by the client and not acked OR got sent to the client side message callbackhandler but never got received by the client. (I.e. they just sat in the buffer).
These should all be cancelled.
3. Clear the client side message callbackhandler buffers for any consumers enlisted in the tx.
4. Call deliver() on the channel.
On rollback/recover:
We must redeliver any messages that were received by the client but not acked by the client.
This set is given by the set of deliveries in the serverconsumerdelegate MINUS the messages in the messagecallbackhandler buffer - we do not want to redeliver these.
1. Cancel only the deliveries corresponding to the message still remaining in the messagecallbackhandler buffers.
2. Any remaining deliveries represent those received by the client but not acked. These must be redelivered (NOTE we are NOT calling channel.deliver() since this delivers any unacked messages).
Unfortunately the current redeliver() method only redelivers to the same receiver, but in our case it may be a different receiver - we need to change this.
3. Now call deliver() this will cause the messages that were in the client side buffer to be redelivered.
NOTE we may have a message ordering problem here.