From: timfox <nu...@jb...> - 2005-05-11 18:17:44
|
Hi All- Further to the discussion regarding asynchronous ACKs, here are some thoughts on how we can implement QueueBrowsing on the core classes and how it all works together. The assumption here is that we want to be able to browse any messages in a queue where delivery has not been attempted. We don't want to browse those messages where the message has been delivered but the JMS client has NACKed it. Currently the core classes don't allow us to distinguish those messages that have not had delivery attempted and those that have. A proposal would be modify the return value of Receiver.handle() from a boolean to one of three states: ACK - the message has been handled sychronously and acknowledged. NACK-DeliveryAttempted - the message is not (yet) acknowledged but delivery is being attempted. NACK-DeliveryNotAttempted - the message is not acknowledged and delivery has not been attempted. The acknowledgement store would also be modified to allow us to distinguish between NACK-DeliveryAttempted and NACK-DeliveryNotAttempted. I.e. it needs to store the tuple <receiver_id, message_id, nack_type (- one of delivery attempted or delivery not attempted)> For the case of a queue: If the queue has no consumers and messages arrive, nacks are stored with state NACK-DeliveryNotAttempted and the messages are stored. The QueueBrowser will only browse NACKed messages with state NACK-DeliveryNotAttempted, so it sees these messages. A consumer is now added to the queue, causing deliver() to be triggered. Messages with either of the two NACK states are sent for delivery. The consumer starts to accept messages for delivery, returning NACK-DeliveryAttempted to the router. A QueueBrowser will not see the messages with state NACK-DeliveryAttempted. As messages are asynchronously acknowledged a callback from the client to the server causes the corresponding NACK to be removed from the acknowledgement store. Currently this is done with a callback interface on the Consumer object (AcknowledgementHandler) which gets invoked from the client, I guess it could also be done by implementing this interface on the Destination classes (??) Messages can be asynch. acknowledged due to either auto acknowledgement, manual acknowledgement, lazy acknowledgement or session commit. For session commit, and potentially lazy acknowledgement and manual acknowledgement I think we also need to extend the Acknowledgement interface to take a batch of acknowledgements as opposed to a single acknowledgement, since the acks must be processed as an atomic unit for transacted sessions, and for the other cases this could help reduce network traffic (although it is probably to early for optimisations at this stage). This also means I think we need to extend the acknowledgement store to be able to process a batch of ACKs (i.e. forget a batch of NACKs) as an atomic unit, otherwise if only some are reliably persisted because of failure in mid operation we have a problem. Message re-delivery should only happen when the consumer (re)connects to the queue, Session.recover() is invoked or transacted session rollback occurs (Is that all cases?), so there should be no problem with the message being redelivered when it's already in mid delivery. If a client dies, then its consumer can be removed, and when it reconnects the nacked messages are redelivered. The behaviour of a durable subscription on a Topic should be almost identical I believe. Actually this should give us, (if we wanted to do some kind of JBoss specific JMS extension), the ability to browse durable subscribers too. Non durable subscriptions shouldn't be affected since we don't store anything. -Tim View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3877372#3877372 Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3877372 |