Rafael Schloming wrote:
Gordon Sim wrote:
Rafael Schloming wrote:
I don't think this is the only difference. A broker can DLQ unacked messages, but not released messages.

What are the rules around that? I would expect unacked messages to be left on the queue, as the delivery hasn't succeeded. DLQing them seems quite wrong to me. Certainly neither of the qpid brokers do that.

I'm not sure the spec has language explicitly stating this, but I had always assumed it was an option. If you can't do this then a message that causes a client to repeatedly crash before it has a chance to reject will effectively block up a queue forever.

I think that is an issue that applications should deal with (or else require administrator intervention). To allow unacked messages to be dequeued seems an extremely bad idea to me unless there is precise rules around it.

The reliability model in my view sets the expectation that a message stays on a queue until acked or until explicitly rejected.

There is also another difference. Released messages will be available to the broker immediately, whereas unacked messages won't be available until the session closes, so a client impl can't depend on recovery of unacked messages for cleanup when it closes a consumer since those unacked messages would be stranded with that client until the whole session closes.

Yes, I agree that release is good for early indication that a message is not required, and would be useful for handling MessageConsumer.close().

As the ack is a key reliability mechanism, allowing arbitrary DLQ decisions based on unacked deliveries seems to me to undermine the ack-based reliability model.

It's not arbitrary. An ack informs you that a message has been processed, but you can't infer one way or another from the absence of an ack, therefore you *have* to deal with the possibility that these messages have been processed already regardless of whether you do it by setting the redelivered flag or by DLQing the message.

What seems arbitrary is the decision to either leave it on the original queue with the redelivered flag set or DLQ the message. Its the latter option I'm against; I don't think its valid behaviour.

Either way I don't think it's acceptable for a routine close of a consumer to cause redelivery of a slew of messages that may already have been processed. It would, for example, be unacceptable to any application that requires human intervention to deal with redelivered messages.

I agree that minimising the number of messages that the broker marks as redelivered is desirable. As I said in the first mail I also think that release is a valuable addition to cater for the case where there is no ambiguity about processed state. My original point was that I didn't see much benefit in retrofitting it to older versions of the protocol.

(Btw, we have been talking about session.close here aren't we? i.e. not MessageConsumer.close() which would I think be a better place for handling any releasing).

[...]
In the case of the no-ack mode, the whole aim is to allow optimisation of the case where redelivery is not required (e.g. often where a client has its own exclusive queue representing a subscription).

That's a good point. Releasing prefetched messages in no-ack mode won't actually do anything since they may have already been discarded. Given that I would fall back to processing all prefetched messages in the case of no-ack and letting the user choose to throw them away if that is appropriate for the application.

I think by closing the session the application is saying it wants to quit. Perhaps the close on the MessageConsumer could do something like this... i.e. don't return from that close until all the messages have been pumped through the listener?

I think this would be reasonable if you wanted to avoid back-porting release to 0-8, but as the code already mis-uses reject to indicate release, I'm not sure there is much point to avoiding it.

My point was that MessageConsumer.close would perhaps be a better place to try and handle the closing of consumer state (being under the assumption that the debate thus far had been focused on Session.close()).

However I don't think that retrofitting release is any better than using reject in a way that may not be portable. Neither cases is guaranteed to work with other brokers, but adding a new method seems even less likely to be interoperable.

Reply via email to