On 5. 11. 13 18:58, Rafael Schloming wrote:
Hi,
I'm scratching my head a bit to understand your scenario so I'll answer the
easy question first. ;-) The address format currently used by messenger
isn't part of any official spec, and the official spec will likely look a
bit different. When the spec is ratified, we will have to change and
probably do some work to maintain backwards compatibility.
in that case it's better to have just one backward compatibility problem
instead of adding
another one on top.
Now as for your scenario, I applied your patch and ran through the scenario
you describe and what I observed was the first reply going from window 1 to
window 3 getting dropped due to the (intentionally) aborted connection, and
the second reply ending up going to window 2 because the window 1 messenger
saw that there was no connection and was able to initiate its own
connection based on the address in the reply_to. What is perhaps a little
odd about this configuration is the fact that the messenger in window 3 has
chosen a dns registered name that collides with the ip/port used in window
2. If you imagine instead that the messenger in window 3 is actually
subscribed to amqp://~127.0.0.1:23456/, then the behaviour could be quite
useful. The server could in fact get a reply back to the client even if the
client's original connection dies.
I fully admit the example is a bit contrieved. the ip-address name was
to ease scenario setup
using the available bits and pieces.
So assuming I understand your scenario/suggestion correctly, I'd say the
ability to choose a dns registered name for your messenger is actually a
feature, not a bug.
The bug part is this: only really simplistic applications will be able
to respond to each request
immediately. As soon as there is any long-running processing (maybe
sending and receiving
another amqp message) required to compute the reply it's much much
easier to come to the
point where reply address will get intermittently interpreted as dns
addresses.
I'll also point out that because the messenger name is
placed in the reply_to address with simple text substitution, you can
always choose your messenger name to be '/foo' instead of foo (or indeed
you could use any illegal domain character) in order to avoid the
possibility of accidental collision.
I like the "/foo" approach but '/' is not a good character as the
resulting reply_to address gets mis-parsed.
try to get an actual reply:
$ ./recv -r & ./send -r -n /foo
...
recv.c:162: unable to connect to amqp:///foo: connect: Address family
not supported by protocol family
Btw, starting the messenger name with "~" and a bit of bad luck will
make the respondent start listening on a new port :)
"Don't do that then" is a good answer :)
Any other illegal domain character seems to fit the bill
here's a proposal for documentation change
---
diff --git a/proton-c/include/proton/message.h
b/proton-c/include/proton/message.h
index 757b076..541cd46 100644
--- a/proton-c/include/proton/message.h
+++ b/proton-c/include/proton/message.h
@@ -86,6 +86,18 @@ PN_EXTERN const char *
pn_message_get_subject (pn_message_t *msg);
PN_EXTERN int pn_message_set_subject
(pn_message_t *msg, const char *subject);
PN_EXTERN const char * pn_message_get_reply_to
(pn_message_t *msg);
+/** Set the reply-to message property
+ *
+ * If the reply_to equals "~" or starts with "~/" then the reply_to
+ * will be rewritten when message is sent with pn_messenger_put(). The
+ * '~' is replaced with "amqp://<name>" where <name> is the name of
+ * the messenger used for sending.
+ *
+ * @param[in] msg the message to modify
+ * @param[in] reply_to the reply-to address
+ *
+ * @return 0 on success or a messenger error
+ */
PN_EXTERN int pn_message_set_reply_to
(pn_message_t *msg, const char *reply_to);
PN_EXTERN pn_data_t * pn_message_correlation_id
(pn_message_t *msg);
diff --git a/proton-c/include/proton/messenger.h
b/proton-c/include/proton/messenger.h
index 5b318bf..f8f7e46 100644
--- a/proton-c/include/proton/messenger.h
+++ b/proton-c/include/proton/messenger.h
@@ -49,6 +49,13 @@ typedef enum {
/** Construct a new Messenger with the given name. The name is global.
* If a NULL name is supplied, a UUID based name will be chosen.
*
+ * Note: See documentation for pn_message_set_reply_to for details how
+ * the name is used. Since the reply address will be re-interpreted by
+ * the responder make sure that the name does not accidentally resolve
+ * as a dns name or even starts with a "~" as that may lead to
+ * messages getting delivered to unexpected destination in certain
+ * edge cases. Name containing "/" should also be avoided.
+ *
* @param[in] name the name of the messenger or NULL
*
* @return pointer to a new Messenger
---
Bozzo