Gordon Sim wrote:
Rafael Schloming wrote:
Gordon Sim wrote:
The only difference between an explicit 'release' and not
acknowledging a message is that the redelivered flag will be set in
the latter case, but not the former.
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.
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.
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. 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.
[...]
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.
--Rafael