I like Option 2 with the addendum. 1. Keeping "Message" purely as a value object without any coupling to any state is very desirable.
2. As Justin mentioned, option 2 allows a clear and more importantly a common approach for handling reliability for both sender and receiver. 3. Messenger.ack() to ack all messages received upto that point is a good compromise for people looking for the more familiar JMS like approach. Regards, Rajith On Sun, Oct 28, 2012 at 2:58 AM, David Ingham <david.ing...@microsoft.com> wrote: > I like option 2 too for the concept separation reasons that have already been > stated. > > The next question is how would an app select which receive mode it's > interested in (auto ack vs. explicit ack). Would this be an option on > Messenger.subscribe()? > > Dave. > > -----Original Message----- > From: William Henry [mailto:whe...@redhat.com] > Sent: Friday, October 26, 2012 12:27 PM > To: proton@qpid.apache.org > Subject: Re: acks for messenger > > +1 I like the separation. And the analogy to tracking is not only palatable > but also kinda proves out the idea. > > William > > ----- Original Message ----- >> I like option 2) for two reasons. One, it produces very >> straightforward semantics for the various levels of delivery >> guarantee. Two, it's easy to ignore if you'd like: if you just want >> fire-and-forget messaging, you don't have to engage delivery as an api >> concept; if you later change your mind, it's not hard to level up. >> >> Justin >> >> On Fri, 26 Oct 2012, Rafael Schloming wrote: >> >> > I'm taking a look at expanding the messenger API to support >> > reliability and so far there seem to be two directions to explore >> > which I'll attempt to describe below: >> > >> > Option 1) >> > >> > Messenger.ack(Message) or possibly Message.ack() >> > >> > I'll describe this as the simple/expected/conservative option, and >> > those really are its strong points. Some less desirable points are >> > that it takes the Message concept in a bit of a different direction >> > from where it is now. Message is no longer simply a holder of >> > content, but it is also now (at least internally) tracking some >> > kind of delivery state. This is undesirable from a design >> > perspective since you're really merging two separate concepts here, >> > delivery state and message content, e.g. you now end up holding >> > onto the message content to track the delivery state when arguablly >> > the common case is that an app will be done processing the content >> > quickly but may care about the delivery state for longer. Another >> > implication of this merging is that it makes messages harder to >> > reuse, e.g. imagine if you want to receive a message, mutate it a >> > bit, and then resend it or send a number of similar messages. >> > >> > It's also potentially more work from an implementation perspective >> > as the underlying model treats Message as pure content and has >> > delivery factored out as a separate concept, so this would be the >> > start of a bit of an impedence missmatch between layers. It's >> > certainly doable, but might result in more overall code since we'd >> > be expressing similar concepts in two different ways. >> > >> > Option 2) >> > >> > Introduce/surface the notion of a delivery/tracking number through >> > the Messenger API, e.g.: >> > >> > Messenger.put(Message) -> Delivery/Tracking-Number/Whatever >> > Messenger.get(Message) -> Delivery/Tracking-Number/Whatever >> > >> > (I'll abbreviate Delivery/Tracking-Number/Whatever as DTW for >> > now.) >> > >> > There are a couple of choices with this option, DTW could be a >> > value object (i.e. similar to a handle), with actions on the >> > messenger itself, e.g. Messenger.ack(DTW), Messenger.status(DTW). >> > This kind of takes the tracking number analogy and runs with it, >> > you ask your messenger about the status of a given delivery via its >> > tracking number. Alternatively, DTW itself could be a more action >> > oriented interface with its own methods for acking/status/etc. This >> > isn't necessarily an either/or as there are reasons the C API might >> > want to use a handle approach even if we wish to >> > conceptualize/surface DTW as more of an independent thing in the >> > object oriented interfaces. >> > >> > On the negative side this is less traditional/expected relative to >> > Option (1), and it does in total add more surface area to the API. >> > On the positive side however it does provide a lot more capability >> > since the same concept extends quite easily to track the state of >> > outgoing deliveries. >> > >> > From a design perspective this is nicer for a couple of reasons, >> > unlike Option (1) by keeping Message as a pure holder of content >> > you have more flexibility with how you use the API, e.g. you can >> > discard/reuse the Message but still track the status of your >> > deliveries. Also, it seems likely that once the Option 1) path >> > includes the ability to track the status of outgoing deliveries, >> > the total surface area balance might fall more in favor of Option >> > (2). >> > >> > A possible addendum to Option (2) suggested by Rob in order to >> > deal with the surface area concerns is adding some kind of >> > Messenger.ack() that would acknowledge all unacked deliveries >> > pulled from the incoming queue. This would enable you to do basic >> > acking without ever needing to bother with DTWs if you don't care >> > about them. This could in fact be a nice place to start as it >> > doesn't necessarily commit us to either path initially. >> > >> > FWIW, my bias right now is towards exploring Option (2). I think the >> > fact that it is less expected is sufficiently mitigated by the fact >> > that with the addendum there is a very gentle learning curve, and >> > even if you explain all the concepts up front, the whole tracking >> > number analogy makes it fairly intuitive. I can even imagine playing >> > up the difference as a selling point from a technical marketing >> > perspective. >> > >> > --Rafael >> > >>