You are viewing a plain text version of this content. The canonical link for it is here.
Posted to proton@qpid.apache.org by Rafael Schloming <rh...@alum.mit.edu> on 2012/10/30 13:15:42 UTC

delivery vs tracker

One of the more vague points of the favored option 2 was what exactly
put/get returns, i.e. the Delivery/Tracking-Number/Whatever thing.
Once again there are two somewhat different directions we could
proceed here:

Option 1) (aka the red pill)

  Delivery (or something that is 1-1 with delivery).

  The delivery class is defined as part of the engine API, and thus it
  quite directly follows the concept of delivery as it is formally
  defined by the AMQP specification. While this class does define all
  the necessary accessors to track the information that is of interest
  to messenger users, it also provides a level of both access and
  control that might be scary and/or downright dangerous to messenger
  users. In particular delivery objects track all the runtime
  communication state associated with a given delivery. As such,
  deliveries are components of links as one would expect given that
  the delivery-id sequence defined in the specification is scoped to a
  containing link, and one can in fact navigate from a delivery oject
  to its containing link, session, and connection. Given this,
  returning delivery directly will pretty much provide full access to
  all the internal engines used by a messenger.

  A less extreme variant of this option would be to provide a facade
  that internally points to the engine's delivery object but only
  exposes functionality deemed safe for messenger users.

  In either case the defining charactaristic of this option is that
  put and get are returning an entity that directly corresponds to a
  delivery.

Option 2) (aka the blue pill)

  Tracking Number

  Return an opaque, passive value object that can be passed back to
  the messenger in order to access and/or update information about a
  particular put/get.

  At first I thought this was a distinction that perhaps didn't make
  sense in an OO context since the "handle" pattern and the "object"
  pattern in C can both easily be exposed as quite similar APIs in an
  OO interface. However, upon more reflection, there is an important
  distinction here even in an OO context. Intuitively a tracking
  number is something that you would expect to be able to save in a
  file or a database, e.g. in Java terms a tracking number might be
  externalizable, whereas a delivery could not be.

  It's also the case that a tracking number does not need to
  correspond 1-1 with a delivery, e.g. a tracking number could be
  implemented with a sequence-id and thereby allow the messenger to
  answer status queries against a given "number" for an indefinitely
  long period. In contrast, every delivery object has an internal
  buffer for its message content, and therefore must have a defined
  scope in order to conserve resources.

My inclination is to persue option 2 for the following reasons:

  - Option 1 introduces more burden since users need to explicitly
    manage the lifecycle of the returned objects. While this burden
    might be mitigated in a garbage collected language, it would quite
    likely significantly impact performance to let the GC manage
    retiring these delivery objects. (The engine underneath messenger
    is quite capable of cycling through hundreds of thousands of
    deliveries per second, and this would most likely put a
    significant burden on any GC subsystem.)

  - Option 1 introduces additional action objects, the user model is
    simpler if all the actions stay with messenger.

  - Option 1 requires coming up with a name for something that is like
    a delivery but not quite.

  - Option 2 potentially offers more capabilities in terms of
    persisting delivery state outside a messenger.

  - Option 2 maps pretty naturally to the protocol notion of
    delivery-tag and lends itself to a pretty easy name/analogy. One
    option is pn_tracking_id_t, however I prefer the slightly more
    abstract pn_tracker_t as it suggests a bit less about how it
    might be implemented under the covers.

--Rafael

Re: delivery vs tracker

Posted by Rafael Schloming <rh...@alum.mit.edu>.
On Wed, Oct 31, 2012 at 7:45 PM, Justin Ross <jr...@redhat.com> wrote:

>
>
> On Wed, 31 Oct 2012, Darryl L. Pierce wrote:
>
>  On Tue, Oct 30, 2012 at 08:15:42AM -0400, Rafael Schloming wrote:
>>
>>> My inclination is to persue option 2 for the following reasons:
>>>
>>>   - Option 1 introduces more burden since users need to explicitly
>>>     manage the lifecycle of the returned objects. While this burden
>>>     might be mitigated in a garbage collected language, it would quite
>>>     likely significantly impact performance to let the GC manage
>>>     retiring these delivery objects. (The engine underneath messenger
>>>     is quite capable of cycling through hundreds of thousands of
>>>     deliveries per second, and this would most likely put a
>>>     significant burden on any GC subsystem.)
>>>
>>>   - Option 1 introduces additional action objects, the user model is
>>>     simpler if all the actions stay with messenger.
>>>
>>>   - Option 1 requires coming up with a name for something that is like
>>>     a delivery but not quite.
>>>
>>>   - Option 2 potentially offers more capabilities in terms of
>>>     persisting delivery state outside a messenger.
>>>
>>>   - Option 2 maps pretty naturally to the protocol notion of
>>>     delivery-tag and lends itself to a pretty easy name/analogy. One
>>>     option is pn_tracking_id_t, however I prefer the slightly more
>>>     abstract pn_tracker_t as it suggests a bit less about how it
>>>     might be implemented under the covers.
>>>
>>
>> +1 on option 2, since it appears to be much more flexible and, as you
>> indicate, keeps the actions in Messenger. This is much more logical IMO.
>>
>
> I personally prefer option 1.  Forgetting for a moment the quite legit
> concerns that Rafi mentions, it produces the better api, imo.
>
> I said before that I liked how users only had to engage delivery when they
> were ready.  From that standpoint, keeping #acknowledge() and #settle() on
> delivery is better.  That way, all the verbs on messenger act conceptually
> on messages.  For some people, that will be the furthest they need to go.
> Then, only if you opt to handle deliveries do you discover the verbs to
> handle delivery state.
>

This is a bit of a tangent, but I think conceptually all the verbs on
messenger are actually acting on deliveries. I know it looks syntactically
like put and get operate on a message, but that is really incidental as the
message object is purely a mutable holder/authoring tool for message
content. What put and get are really doing is creating/accessing a delivery
(i.e. stuffing your letter into an envelope, or opening up the envelope and
giving you the letter).

That said, I buy the concern about lots of handle objects.  For me, this
> refocuses the question on how we might support such objects in at least
> some of the bindings.  I would argue that we want that option.


It should be trivial to wrap the handle in an object that holds a reference
to both the messenger and the tracker. That's not quite what I did in
python (see my other post), however I think what I did has a similarly
small footprint. I think which style makes more sense depends somewhat on
the extent to which these things are used individually or in aggregate,
i.e. if aggregate is the common case, then the tracker as an entity is less
of a fit.

As an aside, I would avoid thinking of an entity wrapping up a reference to
the messenger and a handle as a Delivery, both because that is a distinct
and formally defined concept, and because there are subtle but important
differences. It's really a reference to a delivery that may no longer
exist, and it also has the property of identifying a point in a sequence of
deliveries allowing for identifying ranges of deliveries for aggregate
operations.

--Rafael

Re: delivery vs tracker

Posted by Justin Ross <jr...@redhat.com>.

On Wed, 31 Oct 2012, Darryl L. Pierce wrote:

> On Tue, Oct 30, 2012 at 08:15:42AM -0400, Rafael Schloming wrote:
>> My inclination is to persue option 2 for the following reasons:
>>
>>   - Option 1 introduces more burden since users need to explicitly
>>     manage the lifecycle of the returned objects. While this burden
>>     might be mitigated in a garbage collected language, it would quite
>>     likely significantly impact performance to let the GC manage
>>     retiring these delivery objects. (The engine underneath messenger
>>     is quite capable of cycling through hundreds of thousands of
>>     deliveries per second, and this would most likely put a
>>     significant burden on any GC subsystem.)
>>
>>   - Option 1 introduces additional action objects, the user model is
>>     simpler if all the actions stay with messenger.
>>
>>   - Option 1 requires coming up with a name for something that is like
>>     a delivery but not quite.
>>
>>   - Option 2 potentially offers more capabilities in terms of
>>     persisting delivery state outside a messenger.
>>
>>   - Option 2 maps pretty naturally to the protocol notion of
>>     delivery-tag and lends itself to a pretty easy name/analogy. One
>>     option is pn_tracking_id_t, however I prefer the slightly more
>>     abstract pn_tracker_t as it suggests a bit less about how it
>>     might be implemented under the covers.
>
> +1 on option 2, since it appears to be much more flexible and, as you
> indicate, keeps the actions in Messenger. This is much more logical IMO.

I personally prefer option 1.  Forgetting for a moment the quite legit 
concerns that Rafi mentions, it produces the better api, imo.

I said before that I liked how users only had to engage delivery when they 
were ready.  From that standpoint, keeping #acknowledge() and #settle() on 
delivery is better.  That way, all the verbs on messenger act conceptually 
on messages.  For some people, that will be the furthest they need to go. 
Then, only if you opt to handle deliveries do you discover the verbs to 
handle delivery state.

That said, I buy the concern about lots of handle objects.  For me, this 
refocuses the question on how we might support such objects in at least 
some of the bindings.  I would argue that we want that option.

Justin


Re: delivery vs tracker

Posted by "Darryl L. Pierce" <dp...@redhat.com>.
On Tue, Oct 30, 2012 at 08:15:42AM -0400, Rafael Schloming wrote:
> My inclination is to persue option 2 for the following reasons:
> 
>   - Option 1 introduces more burden since users need to explicitly
>     manage the lifecycle of the returned objects. While this burden
>     might be mitigated in a garbage collected language, it would quite
>     likely significantly impact performance to let the GC manage
>     retiring these delivery objects. (The engine underneath messenger
>     is quite capable of cycling through hundreds of thousands of
>     deliveries per second, and this would most likely put a
>     significant burden on any GC subsystem.)
> 
>   - Option 1 introduces additional action objects, the user model is
>     simpler if all the actions stay with messenger.
> 
>   - Option 1 requires coming up with a name for something that is like
>     a delivery but not quite.
> 
>   - Option 2 potentially offers more capabilities in terms of
>     persisting delivery state outside a messenger.
> 
>   - Option 2 maps pretty naturally to the protocol notion of
>     delivery-tag and lends itself to a pretty easy name/analogy. One
>     option is pn_tracking_id_t, however I prefer the slightly more
>     abstract pn_tracker_t as it suggests a bit less about how it
>     might be implemented under the covers.

+1 on option 2, since it appears to be much more flexible and, as you
indicate, keeps the actions in Messenger. This is much more logical IMO.

-- 
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/