On Tue, Mar 26, 2013 at 7:19 AM, Bozo Dragojevic <bo...@digiverse.si> wrote:
> On 3/23/13 5:43 PM, Rafael Schloming wrote: > >> Hi, >> >> I've added a new API to messenger that gives the user some control over >> the >> internal routing behaviour of a messenger. Please check it out and >> comment. >> I've pasted the C API/doxygen below. This is currently only exposed >> through >> the python binding via the route method on the Messenger class. >> >> --Rafael >> >> /** Adds a routing rule to a Messenger's internal routing table. >> * >> * The route procedure may be used to influence how a messenger will >> * internally treat a given address or class of addresses. Every call >> * to the route procedure will result in messenger appending a routing >> * rule to its internal routing table. >> * >> * Whenever a message is presented to a messenger for delivery, it >> * will match the address of this message against the set of routing >> * rules in order. The first rule to match will be triggered, and >> * instead of routing based on the address presented in the message, >> * the messenger will route based on the address supplied in the rule. >> * >> > > Can you help me work through this use-case: > > > A 'dumb' client, sends a message, and expects a reply: > > // client.c > pn_message_set_address(msg, "amqp://localhost/bla"); > pn_messenger_put(msgr, msg); > pn_messenger_receive(msgr,1); > msg = pn_messenger_get(msgr); > > > > The peer it connects to uses the new route functionality: > > // server.c > pn_messenger_subscribe(msgr, "~amqp://localhost/bla"); > I'm assuming you mean "amqp://~localhost/blah" above. ;-) > > 1) Are routes valid to use if there's a subscribe going on. > I assume yes. > > pn_messenger_route(msgr, "*", "amqp://broker/$1"); > It's certainly valid to use both at the same time. > > 2) How do they interact. > I assume they don't, routing is only applied to outgoing messages. > Actually routing should be applied equally to both, however now that I think about it I suspect you need to do the route before you do the subscribe in order for it to make a difference for the subscribe, although I expect that limitation to go away in the next round of changes. > > 3) Does the order of calls to route and subscribe matter. > According to 2) it does not. > Actually the order does matter (see above). I expect eventually the implementation will evolve in such a way that the order does not matter, however even so you would effectively end up getting a resubscribe when the new route goes into place, e.g. the following sequence of events could occur: subscribe("foo.com/bar") ... ... if you do a recv here, messages might arrive directly from foo.com ... route("foo.com/bar", "fooproxy.com/baz") ... ... now you get messages via the proxy > > pn_messenger_receive(msgr, 1); > msg = pn_messenger_get(msgr); > > /* echo */ > char *sender = pn_message_get_reply_to(msg); > pn_message_set_address(msg, sender); > pn_messenger_put(msgr, msg); > pn_messenger_send(msgr); > > > 4) What would the pn_message_get_reply_to() return. > The value as set by the client's messenger would be > amqp://some-uuid-value > This is a very good question. I don't recall exactly why messenger sets the reply_to automatically as it does, it may even be an unintentional side effect of a couple of different changes, but I've been thinking that it shouldn't actually do this automatically, i.e. that you should always set a reply_to explicitly if that's what you want. FWIW, it's not actually setting the reply_to value to some-random-uuid, it's actually setting it to amqp://the-name-of-the-messenger. It just so happens that the name of the messenger defaults to a UUID, but if you had constructed your messenger as pn_messenger("bob") rather than pn_messenger(NULL), then the reply_to would automatically get set to amqp://bob. I was also thinking that it would be convenient to have some way to actually refer to the container name in an address, that way e.g. explicitly setting the reply_to = "amqp://${me}" would give the same effect that you currently get with the automatic setting, but would also be a bit more flexible. > > 5) Would the route above apply or not to this particular outgoing reply > message. > The rules always apply, the messenger impl doesn't really know the difference between that and any other address. > > 6) If yes, how will 'broker' learn how to talk to the original client > Another very good question. Unfortunately the answer right now depends on your broker as each broker assumes a private namespace, you would need to construct a reply_to that is known to your broker, e.g. create a reply-queue called "replies" on your broker and explicitly set your reply-to to amqp://broker/replies. One of the areas that we are working on within the OASIS TC is defining an addressing standard such that this will be much more seamless, e.g. the clients could just use globally scoped names the same way they would in a peer to peer scenario, and you could have an intermediary that would be able to identify these and route/proxy accordingly. Obviously a legacy broker wouldn't necessarily function as a router/proxy, so you still might need to manually stitch together the reply-to chain depending on what kind of intermediary you are using. One thing worth pointing out about this functionality that might not be obvious at first is that the route function doesn't currently touch what is in the to or reply-to field of a message. That always stays exactly as the user supplies it. The model is really a world where logically the to and reply-to identify a final destination/rendezvous point and therefore need to be preserved and carried forward by every intermediary in the network. Hence the name pn_messenger_route as what it is doing is determining the next hop, not doing some sort of rewriting. It would, however, be possible to add an API that used the same or a similar mechanism to do rewriting, e.g. pn_messenger_rewrite(pn_messenger_t *m, const char *pattern, const char *address) could establish a distinct set of rules for rewrite the to/reply_to of incoming and/or outgoing messages. I can imagine this possibly being useful in legacy scenarios where you need the reply_to to match a particular form required for a given broker. --Rafael