On Thu, Oct 6, 2022, 19:07 Timothy Bish <[email protected]> wrote:
> On 10/6/22 12:19, Jiri Daněk wrote:
> > On Thu, Oct 6, 2022 at 5:19 PM Timothy Bish <[email protected]> wrote:
>
[...]
> 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();
> > }
>
(NB. This is not a busy loop involving the network, because sooner or later
the peer will drain my credit, if it intends to keep blocking me. And
sender.send() blocks upon running out of credit, as was already said
before.)
Anyways, the above forces me to have only one message in flight even though
applications can usually benefit from having multiple messages in flight.
Seems like it should work for your test case, other options are to delay
> resend (possibly with back off) or resend up to some max limit,
I don't see much point in those sophisticated strategies with delays, etc
for resends (as opposed to reconnect). When the remote peer stops accepting
messages, it should be either because there is something wrong with the
messages (and then there is no point in resending the same thing again) or
because the peer is unable to handle any messages right now, and then it
should drain my credit. Plain send attempt (which blocks on having credit)
should then be the most appropriate answer.
(Peer can't simply drain credit for anonymous producers, I guess, so ok,
maybe there is a point in these client-driven retry strategies sometimes.)
> all of
> which will depend on your application and how you decide to handle send
> errors.
One could make the same argument against providing reconnect and reconnect
strategies (exponential delay, maybe with jitter) in an AMQP library.
> > 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.
>
> We chose to keep the included samples small and concise as a "production
> ready" example tends to not be production ready based on how your own
> application chooses to respond to errors etc and the samples quickly
> become to complex for a novice user to get started.
>
> 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 specification defines the meaning of each state
>
>
> http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#section-delivery-state
>
> You application then needs to decide how to best handle / report those
> outcomes.
>
How does a typical messaging user learn what possible dispositions might
their broker (let's use Artemis as an example) issue, and how these map to
different broker features? Looking at that AMQP spec in isolation, I
certainly would not realize there is logic needed to handle full addresses.
Do I really need to read the broker docs from cover to cover? (
https://activemq.apache.org/components/artemis/documentation/latest/flow-control.html,
section Blocking AMQP Producers; moreover, the docs say "Once this upper
bound is reach Artemis will start rejecting AMQP messages." It does not
make any explicit reference to AMQP dispositions, so it can be easily
missed when searching for it).
In the AMQP world, it is even possible to write portable clients, or are
the differences and gotchas between different peers (Artemis, Dispatch
Router (which does not always grant credits to receivers by default...), or
Azure Service Bus) so great that it is necessary to focus on one, and then
there is extensive testing required to catch all those quirks? And every
user of the peer has to discover them for themselves, when building a
client?
On Thu, Oct 6, 2022 at 8:43 PM Connie Yau <[email protected]>
wrote:
> Hey,
>
> You can take a look at the Tracker object returned from a send operation
> to understand the state of that message. For example, you could use
> `Future<Tracker> settlementFuture()`
> https://github.com/apache/qpid-protonj2/blob/main/protonj2-client/src/main/java/org/apache/qpid/protonj2/client/Tracker.java#L93
> and
> await it then examine the remoteState() for that returned Tracker.
>
> I hope this helps,
> Connie
>
Thanks, yes, that is a start.