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]