Hi All,

I wanted to re-raise Ted's suggestion regarding the need for a better Messenger 
API for handling reply-to's.

I've could've used this recently while designing a "echo" stress test for 
Messenger.  For my client, I have two requirements:

1) I don't want to have to assign a publicly visible address to the client in 
order to receive replies.

2) I only want a reply for particular messages.

I think these two requirements are common enough to merit some Messenger API 
lovin'.

In that context, Ted's API recommendation makes my life as the client writer 
easier:  It doesn't require me to obtain a reply-to value up-front (ie. before 
calling pn_messenger_put()), and it doesn't cause every message to be sent with 
a reply-to (which, I believe is the current case - messenger always adds a 
reply-to if not set).

I think there's value in Ted's proposal, but I'd recommend a slight 
modification to it: rather than mark the message directly, instead indicate to 
Messenger that a particular message needs its reply-to set correctly prior to 
transmitting it.  For example, we could add a flag to pn_messenger_put():

   msg = pn_message();
   pn_message_set_address( msg, "peer's remote address" );
   .... set message contents, cid, etc ...
   pn_messenger_put( messenger, msg, PN_SET_REPLY_TO );


Setting the PN_SET_REPLY_TO would cause Messenger to set the reply-to properly 
prior to sending, or signal an error if unable to do so (reported via a 
tracker, as usual).

This API change would satisfy my two requirements, while keeping the whole 
address management stuff out of my client.

Thoughts?

-K


----- Original Message -----
> From: "Rafael Schloming" <r...@alum.mit.edu>
> To: proton@qpid.apache.org
> Sent: Friday, January 18, 2013 9:13:34 AM
> Subject: Re: Proton Messenger and the Request/Response pattern
> 
> Gordon makes some good points. I'd like to add that I think
> historically a
> big part of the hassle isn't actually necessarily solely the API but
> also
> having to configure and manage the intermediary, and I think we need
> to
> look there as well if we want to simplify the overall pattern.
> 
> It's also worth remembering that there are significant performance
> benefits
> to keeping Message as a pure value object (i.e. a content holder)
> that can
> be reused many times even across multiple Messengers. Some of the
> suggestions really stray from this pattern. If I recall correctly, I
> think
> we said in prior threads that we wanted to maintain the notion of
> Message
> being a reusable content holder as an architectural invariant.
> Perhaps it's
> worth re-examining what we could do for request/response while
> keeping this
> invariant in mind.
> 
> --Rafael
> 
> On Fri, Jan 18, 2013 at 6:24 AM, Gordon Sim <g...@redhat.com> wrote:
> 
> > On 01/02/2013 07:14 PM, Ted Ross wrote:
> >
> >> I'd like to start a discussion on how, from an API perspective,
> >> applications can use the request/response pattern.  If we get this
> >> right, we will remove a significant barrier to adoption of AMQP.
> >>
> >> Middleware messaging systems typically do a poor job of supporting
> >> this
> >> pattern.  The Qpid APIs are quite lacking in this regard
> >> (requester
> >> creates and subscribes to a temporary queue with a _unique_ name
> >> and
> >> places this name in the reply-to field).
> >>
> >> Proton Messenger supports request/reply (see
> >> examples/messenger/$LANG/{**client,server}) as follows:
> >>
> >> The requester (client) has to put _something_ into the request
> >> message's
> >> reply_to field.  It also sets the correlation_id field if it needs
> >> to
> >> dispatch multiple responses.  The responder (server) must copy the
> >> request message's reply_to field to the response message's address
> >> field
> >> and also copy the correlation_id.
> >>
> >> This API is good for the case where the client wants the response
> >> to go
> >> to a third party.  In this case the reply_to is well understood to
> >> be
> >> the address of the third party receiver.  However in the more
> >> common
> >> case where the response is intended to come back to the client,
> >> it's not
> >> clear at all what to put in the reply_to field.
> >>
> >> I propose that we allow the client to simply say
> >>
> >>      request_msg.reply_expected(**cid)
> >>
> >
> > A message has no association with a messenger (until it is put onto
> > the
> > messengers outgoing queue at least). It is not clear how a method
> > on
> > message would therefore be in any better position to determine the
> > reply-address to use.
> >
> > At present, if a message on the outgoing queue has no reply-to set,
> > then
> > the messenger will automatically set the reply-to to be an address
> > corresponding to itself.
> >
> > You can also use the (in my view slightly clumsy) syntax ~/xyz,
> > which will
> > be 'munged' into a form that prepends the messengers name to form a
> > full
> > address. This form I presume would be used if you want to
> > distinguish
> > different categories of replies.
> >
> > I'm not exactly enamoured with this, but it does seem at least to
> > address
> > the key concern expressed here, namely what to put in the reply-to
> > for the
> > simple case. (The answer being, nothing!)
> >
> >
> >  (I added the correlation_id argument because it's almost always
> >  going to
> >> be needed).  Further, the server could use
> >>
> >>      reply_msg.in_reply_to(request_**msg)
> >>
> >> which would take care of the addresses and the correlation_id.  It
> >> also
> >> provides a place to report an error if a request cannot be replied
> >> to
> >> (absent or invalid reply_to address) rather than force each server
> >> implementer to code this check.
> >>
> >
> > This is really just a short hand for:
> >
> >   response.address = request.reply_to
> >   response.correlation_id = request.correlation_id
> >
> > plus some code or exception indicating whether the address has been
> > set. I
> > have no objection to such a utility, though I'm not entirely
> > convinced that
> > a method on message is the best place. It also seems of fairly
> > marginal
> > benefit rather than removing a 'significant barrier to adoption'.
> >
> > Have you seen the JMS solution to simplifying the request-response
> > pattern? There it is done by specifying a distinct class that uses
> > a
> > supplied session and destination and provides a request() method
> > that takes
> > a request message as input and blocks until it can return the
> > response
> > message. (See http://docs.oracle.com/javaee/**1.4/api/javax/jms/**
> > QueueRequestor.html<http://docs.oracle.com/javaee/1.4/api/javax/jms/QueueRequestor.html>).
> > Details of creating temporary response queues etc are hidden behind
> > this. I
> > like that general approach as it layers the functionality cleanly
> > on top of
> > the more flexible base, and would also allow different
> > configurations or
> > conventions to be used.
> >
> > --Gordon.
> >
> >
> 

-- 
-K

Reply via email to