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).
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.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]