On Thu, Oct 6, 2022 at 5:19 PM Timothy Bish <tabish...@gmail.com> 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) 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(); } > > 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! Also, what changes when transactions are involved on top of this? -- Mit freundlichen Grüßen / Kind regards Jiri Daněk