qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Lam <michael....@rubikloud.com>
Subject Re: Indivdual Message Ack over JMS (warning: ugly hack inside)
Date Tue, 24 Jan 2017 21:56:13 GMT
Thanks.  Good thing JMS Session guarantees onMessage cannot be called
concurrently, so this feature is still quite useful :)

On Tue, 24 Jan 2017 at 16:23 Michael Lam <michael.lam@rubikloud.com> wrote:

Turns out that there's a caveat - the setting of JMS_AMQP_ACK_TYPE stores
the ack type in the a JmsAcknowledgeCallback object, which is in turn used
for all acknowledgements for messages.  So unless a call to
Message.acknowledge() is called immediately and atomically after
setIntProperty(JMS_AMQP_ACK_TYPE, RELEASED), Disposition ack type will be
shared across messages even if their JMS_AMQP_ACK_TYPE are set differently.

Was expecting AmqpConsumer.acknowledge(ACK_TYPE) to read the ack type from
each delivery and override the passed-in parameter.

So make sure if you're using the mechanism, always call
message.acknowledge() immediately after setIntProperty(JMS_AMQP_ACK_TYPE).

On Tue, 24 Jan 2017 at 15:23 Michael Lam <michael.lam@rubikloud.com> wrote:

Ah, totally understood now.  As it is, this partial implementation seems to
be working.  I don't mind acking all the messages if we get to assign the
disposition per-message.  Thanks for the insights again and I'll keep an
eye on updates.

On Tue, 24 Jan 2017 at 15:11 Robbie Gemmell <robbie.gemmell@gmail.com>

The value set on the specific message upon which acknowledge() is
called will be applied to all unacked messages on the session at the
time, i.e regular JMS client-ack mode semantics, just with control
over what type of disposiiton is used for the 'acks' sent due to that
acknowledge() call. The intent was to make it per-message by combining
with the individual-ack mode once introduced in JMS.

On 24 January 2017 at 14:59, Michael Lam <michael.lam@rubikloud.com> wrote:
> Is it per message in a sense that each message will be acknowledged with
> AMQP disposition for its own JMS_AMQP_ACK_TYPE?  If it is the case, it
> would be per-message enough for this purpose....
> On Tue, 24 Jan 2017 at 14:28 Robbie Gemmell <robbie.gemmell@gmail.com>
> wrote:
> It isn't per-message (unless you can ack every message as you receive
> it, before seeing the next one, in which case it is effectively
> per-message) but rather per-session acking of all unacked messages,
> but the intent was it would become fully per-message once JMS added
> individual ack, which seemed well under way in terms of discussion for
> inclusion in JMS 2.1: https://java.net/jira/browse/JMS_SPEC-95. Now
> that JMS 2.1 has been dropped from Java EE 8 the situation is less
> clear.
> On 24 January 2017 at 14:05, Michael Lam <michael.lam@rubikloud.com>
>> Hi Robbie, thanks again - just as I thought I have exhausted all means of
>> achieving this, the mailing list shows me another possibility.  I was
>> totally prepared to implement client-side message persistance and client
>> resend / recover in case nothing works - it's simple but carries too much
>> baggage.
>> My use case needs to selectively RELEASE or ACCEPT the message based on
>> whether the content of the message matches an external state, so I cannot
>> apply the same disposition type to all unacknowledged message - or is the
>> disposition type evaluated on a per-message basis?  If it works
>> per-message, I can at least use a less ugly hack :)
>> On Tue, 24 Jan 2017 at 13:26 Michael Lam <michael.lam@rubikloud.com>
> wrote:
>>> 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
>>> 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
>>> extraction of the JmsInboundMessageDispatch envelope in
>>> 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
>>> 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
>>> Cheers,
>>> Michael
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@qpid.apache.org
> For additional commands, e-mail: users-help@qpid.apache.org

To unsubscribe, e-mail: users-unsubscribe@qpid.apache.org
For additional commands, e-mail: users-help@qpid.apache.org

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message