Hi Guys,
just my 2p worth, but I have to say I'm not at all convinced by any of this.

I personally don't see what's wrong with the standard model for the request/response pattern of requiring a reply-to address and an optional correlation ID.

A key point here is that this is and has been for some time the de facto request/response model across most messaging systems and from my perspective messing around with it is likely to add confusion and actually add a barrier to adopting AMQP. I'm not exactly clear why the current model is seen by anyone as a barrier to adopting AMQP - is this actually the case? I'm dubious because the model described here is exactly the same as the approach used in the JMS API.

Actually the JMS bit is significant too, clearly Qpid is more than just JMS and is clearly a lot more platform agnostic, but I'd certainly wish to avoid API divergence as far as possible without good reason. For sure there are useful things that can be done in qpid::messaging that aren't part of the JMS API but mostly these are to do with Qpid/AMQP optimisations for message pipelining/asynchrony/prefetch etc.


BTW Ted said " It also sets the correlation_id field if it needs to dispatch multiple responses.", I'm sure that you know this, but the correlation_id is also used for the asynchronous request/response pattern where a response might occur some time after the initial request - that model is used in QMF2 for query subscriptions among other things.


There's a suggestion in this thread that "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'm not sure that's the case at all in the following code snippet from my QMF2 API Implementation

"
Destination destination = (replyHandle == null) ? _replyAddress : _asyncReplyAddress;
            MapMessage request = _syncSession.createMapMessage();
            request.setJMSReplyTo(destination);
            request.setJMSCorrelationID(replyHandle);
            request.setStringProperty("x-amqp-0-10.app-id", "qmf2");
            request.setStringProperty("method", "request");
            request.setStringProperty("qmf.opcode", "_query_request");
            request.setStringProperty("qpid.subject", agentName);
"

It was pretty clear to me that the replyTo destination was my main replyAddress for synchronous responses and the asyncReplyAddress (which was on a different Session) when a replyHandle was set and so related to the asynchronous request/response pattern.


Actually that also makes me think that the logic of the statement "However in the more common case where the response is intended to come back to the client" is flawed in the sense that this appears to be asserting that a given client will only have a single replyTo address - sure that'll be the case in many instances, but as above if one wants a mixture of synchronous and asynchronous request/response a client will need at least two addresses bound on different sessions.

There's also an assertion in this thread "requester creates and subscribes to a temporary queue with a _unique_ name" again that's true in *most* cases, but it's important to consider that it isn't always the case that a temporary queue is used. For a scenario where we want a request/response where the request may take a very long time the client may have a named durable queue so that if the actual client was "down for maintenance" when the service provider happened to send it's asynchronous response + cid when the client comes back up it'll actually get the response. If the service provider is doing some expensive processing you really won't want to miss the response when it finally occurs :-)

Sorry I don't mean to sound like I'm on my high-horse, but I'm not at all keen on messing around with a fairly well understood and pretty standard messaging pattern.


If the proposal is simply for an _additional_ API that may be used as a "shorthand" then perhaps that's OK, but I still thing we should be wary of adding additional variance between Java and C++ APIs without good reason. I still wince at the confusion caused by qpid::messaging and qpid::client (It has taken me ages to get some of my colleagues off qpid::client) so if you are planning on adding some sugar I'd definitely prefer to see it in a new namespace so it's pretty easy to differentiate between the *core* messaging APIs and additional abstractions built on those APIs. If that is done then it should also be possible to add an additional Java package that uses new Qpid specific APIs built on top of vanilla JMS.



FWIW I'd actually prefer to see the effort put into getting the C++ QMF API up to spec. I don't know if things have changed since the last time I looked but the QMF2 stuff for C++, whilst it conforms to the QMF2 protocol, doesn't bear any resemblance at all to the QMF2 API spec. If you want to really provide an abstraction for request/response you won't get much more of an abstraction than something like:

......
QmfConsoleData queue = _queueCache.get(queueName);
......

QmfData arguments = new QmfData();
arguments.setValue("request", (long)(_purge*msgDepth));
queue.invokeMethod("purge", arguments);


As you know all of this stuff is built on the request/response patterns and there are pretty regular postings on the mailing list from people wishing to manipulate/get tats from queues etc. from within normal messaging apps. Clearly it's possible using the QMF2 map message protocol if you know what you're doing but there's too little consistency cross language despite there being a well specified protocol and API, so personally I'd find that more productive than tinkering with fairly standard patterns.

All just IMHO of course :-)


BTW what *exactly* is Proton, I've seen a few references to it but nothing is especially clear to me, is Proton the name for the AMQP v1.0 version of Qpid? How does it differ from say Qpid v0.20? Will Proton end up being Qpid v1.0?


Best regards,
Frase


On 02/01/13 21:58, Ted Ross wrote:

On 01/02/2013 02:39 PM, William Henry wrote:

----- Original Message -----
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)
Could you even block here with:

        reply_msg = request_msg.reply_expected(cid)

You can have a default parameter that indicates blocking. And you could

        request_msg.reply_expected(cid, FALSE)

and then do the usual check for incoming messages etc.

I really like this suggestion. The blocking variant is dirt simple and you don't even need to supply a correlation_id. It can be hidden beneath the API.

I do think there may be a cleaner syntax/naming for this though.

An alternate syntax for the client side might be to provide an alternative to "put" like "put_request" that annotates the message appropriately for request/response and returns the correlation_id. "send_request" could be the blocking variant.


(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.
Yeah, that's nice too. I see your point. I'm not sure if all messaging purists will agree. But it makes sense to me that we need something to handle this common use case more effectively.

William

Thoughts?

-Ted




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to