On Thu, 6 Oct 2022 at 17:20, Jiri Daněk <[email protected]> wrote:
>
> On Thu, Oct 6, 2022 at 5:19 PM Timothy Bish <[email protected]> wrote:
>
> > On 10/6/22 10:36, Jiri Daněk wrote:
> > > In my code [1], I create a sender using connection.createSender(), that
> > is,
> > > I don't use Session at all. The Artemis broker on the other side is
> > > configured to BLOCK incoming messages if the queue exceeds a certain
> > > configured size. In AMQP terms, the broker sends disposition of Rejected,
> > > which looks this way in Wireshark
> > >
> > > Advanced Message Queueing Protocol
> > > Length: 135
> > > Doff: 2
> > > Type: AMQP (0)
> > > Channel: 0
> > > Performative: disposition (21)
> > > Arguments
> > > Role: receiver
> > > First: 47
> > > Last: 47
> > > Settled: True
> > > Rejected
> > > Error
> > > Condition: amqp:resource-limit-exceeded
> > > Description: Address is full:
> > > test_broker_blocks_client_many_messages_in_queue
> > >
> > > (See zipped capture file at
> > >
> > https://github.com/rh-messaging/cli-java/issues/455#issuecomment-1270166736
> > )
> > >
> > > However, my program does not respond to this as if the messages were
> > > delivered correctly, and sends detach and then close. The rejected
> > messages
> > > then disappear.
> > >
> > > Do I need to examine the returned Tracker objects and check what became
> > of
> > > my messages? Does the library "take responsibility" for the message the
> > > moment I call send, so I can assume any necessary buffering and
> > redelivery
> > > will be taken care of? Is this supposed to work even if there is, say,
> > > reconnect/failover between brokers while I am sending?
> >
> > Send returns the tracker for you to examine and or wait on the
> > settlement future so that you can ascertain if the remote has accepted
> > or rejected the delivery, the client does not attempt to buffer any
> > messages other than the singular case of a send that blocks because
> > there is not credit in which case that blocked send will either succeed
> > (as in writing it to the wire but still could be rejected) if credit is
> > granted or it would fail if the link was closed (connection dropped
> > etc). The trySend method exists to avoid that blocking behavior if your
> > application doesn't want to deal with blocking on lack of credit scenario.
> >
>
> I guess I've been spoiled by other Qpid clients which do handle some
> resends. Although I don't think that any AMQP client automatically handles
> reconnects/failovers (so that no messages are lost)
>
None of the other clients 'resend' upon explicit reject etc to my
knowledge, they all punt to the application code in effectively
exactly the same way. Their examples might try though, e.g the proton
'container' style clients all fire separate callbacks with the result,
very much analogous to using the tracker to identify the result, and
some of the examples leverage the accepted callback to count (without
regard for _which_ message was actually accepted) the number of
accepted messages and begin from that count if disconnected.
The key difference is more in the buffering or lack thereof. Your PR
talks about 'pretending to send', which it hasnt. Ironic since the
other proton clients effectively do, as calling send on them only
buffers the message and doesnt actually do any IO and so never sends
anything, which only happens later when the container thread unwinds
back to IO processing.
> Sounds like the right strategy for me (at least, to solve my immediate
> problem) is
>
> Tracker tracker = sender.send(message);
> tracker.awaitSettlement();
> while (tracker.remoteState() != DeliveryState.accepted()) {
> // TODO: am I supposed to increment `delivery-count` of the
> message if I got rejected before?
> // as per
> http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#type-rejected
> tracker = sender.send(message); // resend the message
> tracker.awaitSettlement();
> }
>
Incrementing delivery count on initial send by a producer isnt
typical, though you could do so. Theres a consideration of whether the
producer is 'a conceptual queue of sorts' and 'is it the same message,
or an equivalent message, on resend' meta discussion. Of course, the
main thing bumping it is likely to achieve is that the thing you are
resending to in a loop might be more likely to refuse it if it looks
at that, and if its e.g a broker you may even also be burning
potential delivery attempts to an ultimate consumer later.
>
> > > Is this reject disposition-related behavior a client bug? (After thinking
> > > more about it, having written the above, I became convinced it probably
> > is.)
> >
> > Not a bug as far as I can see as it sounds like it is working as
> > intended, and there are tests checking for same.
> >
>
> Is there an example? Looking at
> https://github.com/apache/qpid-protonj2/blob/f215929395e44a8a0679befe15f96fd95b634c16/protonj2-client-examples/src/main/java/org/apache/qpid/protonj2/client/examples/Send.java#L47,
> that waits for the settlement, but it does not check what it is. So, if the
> peer rejects the message, the Send example finishes without reporting any
> errors. AFAIK none of the examples does actually check the
> tracker/disposition. One-way ack sounds to be the default that most users
> will want.
>
> To be honest, I am not entirely clear what are the reasonable responses to
> getting rejected, modified, or released dispositions. So a more
> production-ready =copypastable example of "I just want to send a message"
> would be very welcome!
>
The reasonable response will usually be application dependent; some
will want a resend, others will want to send the next thing because
the last one is no longer important. The client has no idea whats
reasonable. For comparison, the JMS client, if doing a synchronous
send as you appear to actually want here, would throw in all the
non-accepting cases, the application is the only one that can decide
how to handle it.
> Also, what changes when transactions are involved on top of this?
> --
> Mit freundlichen Grüßen / Kind regards
> Jiri Daněk
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]