Hello, I've been trying out some code based on the clone client/server example code in the 0MQ Guide (clone.c, clonecli6.c and clonesrv6.c, zmq v 3.2.2). As with other ZMQ code I've tried so far, the example code builds and runs cleanly - ZMQ is very nice that way. The clone client/server appear to do essentially what I need in an application. As a starting point, I'm using clonecli6 as-is, and wrote a clone client in C using the clone class; it is very similar to clonecli6.c, but another thread catches and handles signals. There is one thing I am confused about, that I haven't seen posted on the archives: When clone_get() is invoked, should the return value be treated as a kvmsg or as a string? I ask because it looks like the clonesvr6/clonecli6 example works as follows: The clonesvr6 stores a key:kvmsg pair in its hash map (stores entire kvmsg received from clone agent). The clonecli6 agent stores a key:string pair in its hash map when it receives a SET message from clone_set(). The clonecli6 agent stores a key:kvmsg pair in its hash map when it receives a a (kvmsg) update from clonesvr. Does that mean that a client's zhash_lookup ( in clone_get() ) may return either a string or kvmsg, depending on whether the server is running and the state of the transaction between the clone agent and clonesvr? So, I'm unclear about whether clone_get is intended to return a string value, or a kvmsg. The clonecli6.c example only posts updates and never calls clone_get(), so the ambiguity isn't apparent until I try to write a client that subscribes to the (clonecli6) updates. To illustrate, if I modify the clonecli6.c to update a single subtree ("/client/" instead of "/client/randof(10000)"), I expect the following client to consume updates produced by clonecli6: #include "clone.c" #define SUBTREE "/client/" int main (void) { // Create distributed hash instance clone_t *clone = clone_new (); // Specify configuration clone_subtree (clone, SUBTREE); clone_connect (clone, "tcp://localhost", "5556"); clone_connect (clone, "tcp://localhost", "5566"); // Set random tuples into the distributed hash while (!zctx_interrupted) { // Set random value, check it was stored char key [255]; sprintf (key, "%s", SUBTREE); printf("clone requesting key %s\n",key); // What does clone_get really return? char *sval=clone_get (clone, key); if(sval!=NULL){ int len=strlen(sval); printf("message value len %d:\n",len); printf("[%s]\n",sval); if(len>1){ kvmsg_t *kval=(kvmsg_t *)sval; byte *mbody=kvmsg_body(kval); printf("kval: [%s]\n",(char *)mbody); }else printf("message len <= 1\n"); }else{ printf("NULL message \n"); } sleep (1); } clone_destroy (&clone); return 0; } Maybe I'm doing something wrong, but in addition to my uncertainty about the return value of clone_get(), this client crashes:
I believe this is caused by the clone agent_control_message GET handler (clone.c:284) calling free(value), which releases the memory reference returned by clone_get. Even if I change comment out that free(value) the example still does not return valid strings (or a kvmsg). In my own application, I modified the clone agent update handler so that it only ever stores string values (never kvmsg) in its hash map. So, only string values are returned by clone_get(). I also eliminated the aforementioned free(value) in clone.c. Doing so seems to work, and valgrind indicates no memory leaks. Have I stumbled upon an issue with this example, or do I misunderstand how the clone example should work? Kent Headley ================================== Monterey Bay Aquarium Research Institute 7700 Sandholdt Road Moss Landing, CA 95039 |
_______________________________________________ zeromq-dev mailing list [email protected] http://lists.zeromq.org/mailman/listinfo/zeromq-dev
