----- Original Message ----- > From: "Michael Goulish" <[email protected]> > To: [email protected] > Sent: Thursday, March 7, 2013 9:48:24 AM > Subject: Re: Proton Messenger and the Request/Response pattern > > > > ----- Original Message ----- > > 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 ); > > > > > I think this requires little or no change to the user's mental model, > which is a _good thing_. > > But wouldn't the following be more natural? : > > pn_message_set_address( msg, peer_addr, PN_SET_REPLY_TO ); > > The address setting is done when your code is thinking about > addresses, > and put() only puts. > >
This would require the message object to contain some extra state, since the reply-to address may not be known at the point the pn_message_set_address() is invoked. That extra state - a flag to tell Messenger to fill in the reply-to - is kinda sorta Messenger specific information that would be piggybacked on the message. I seem to recall the consensus was against that. /my memory ain't what is once was.... > > > > > > > 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" <[email protected]> > > > To: [email protected] > > > 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 <[email protected]> > > > 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 > > > -- -K
