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

Reply via email to