This topic was brought up quite a few times so I'm not here to ask for the
feature. Instead, it is an attempt to share some workarounds, some might
find it useful, some might not.
Broker: Azure Message Bus (it could be useful for some other AMQP 1.0
brokers too).
It supports a "peek lock" mode, where a receiver is given exclusive access
to a message until it is "unlocked" (and it'll be redelivered) or
"deleted". The broker automatically unlocks a message after the "peek lock
timeout".
In AMQP-ish speak, the broker will periodically re-enqueue a message until
a client ACCEPTS ("deletes") or RELEASES ("unlock") it.
AMQP supports individual message acks, but JMS doesn't. Now, if the broker
fully supports JMS delayed delivery, the effect of releasing a single
message can easily be achieved by the receiver re-publish any message it
does not want to acknowledge, asking the broker to delay the enqueue.
So this was the first venue I pursued. Unfortunately, I found out that
Azure Service Bus's scheduled publishes is exposed through AMQP Management
request/response of Azure extensions, instead of recognising the
"x-opt-delivery-time" message annotation. Hopefully this can change.
Meanwhile, after looking at the Qpid JMS Client (verison 0.20), I was able
to devise a contained hack (ugly because it makes use of non-public fields
and methods, but only a few lines of logic) that essentially:
1. wrap around a JmsConnection with a custom ProviderListener that allows
extraction of the JmsInboundMessageDispatch envelope in onInboundMessage,
which runs before onMessage. This allows me to store a map that goes from
JMS Message Id to the envelopes.
2. instead of calling Message.acknowledge(), a call to
JmsConnection.acknowledge(JmsInboundMessageDispatch, ACK_TYPE) is made for
the envelope remembered in step 1 above. If it is called with RELEASE, it
will redeliver the message right away. If it is called with ACCEPT, the
single message is acknowledged and removed. If the calling of acknowledge
is skipped, after the peek lock timeout, the message will be redelivered -
so it will ack like a "RELEASE with delayed redelivery".
After some testing it seems to allow me to sneak in a non-standard
acknowledgement type. I still hope that delayed publish will one day work,
though, understanding this hack probably won't work with the next Qpid JMS
Client release.
(I know that simply re-publish a message, even without a delay, can roughly
simulate a message RELEASE, but having the message redelivered immediately
is not what I'm after).
It may help, or it may serve as a warning about what NOT to do with Qpid.
Cheers,
Michael