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.


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.

Reply via email to