<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Aug 8, 2013, at 9:01 AM, Kai Zhang <<a href="mailto:kyle@zelin.io">kyle@zelin.io</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none; ">On Aug 8, 2013, at 7:08 AM, MORITA Kazutaka <</span><a href="mailto:morita.kazutaka@gmail.com" style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">morita.kazutaka@gmail.com</a><span style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none; ">> wrote:</span><br style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><br style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><blockquote type="cite" style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><blockquote type="cite"><br>-static int zk_get_least_seq(const char *parent, char *least_seq_path,<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-converted-space"> </span> int path_len, void *buf, int *buf_len)<br>+static int zk_acquire_lock(const char *path)<br>{<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span>char path[MAX_NODE_STR_LEN], *p, *tmp;<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span>struct String_vector strs;<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span>int rc, least_seq = INT_MAX , seq;<br>-<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span>int rc;<br><span class="Apple-tab-span" style="white-space: pre; "> </span>while (true) {<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>RETURN_IF_ERROR(zk_get_children(parent, &strs), "");<br>-<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>FOR_EACH_ZNODE(parent, path, &strs) {<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>p = strrchr(path, '/');<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>seq = strtol(++p, &tmp, 10);<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>if (seq < least_seq)<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>least_seq = seq;<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>}<br>-<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>snprintf(path, MAX_NODE_STR_LEN, "%s/%010"PRId32,<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-converted-space"> </span>parent, least_seq);<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>rc = zk_get_data(path, buf, buf_len);<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>rc = zk_create_node(path, "", 0, &ZOO_OPEN_ACL_UNSAFE,<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-converted-space"> </span> ZOO_EPHEMERAL, NULL, 0);<br><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>switch (rc) {<br><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>case ZOK:<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>strncpy(least_seq_path, path, path_len);<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return ZOK;<br>-<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>case ZNONODE:<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return rc;<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>case ZNODEEXISTS:<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>sleep(1);<br></blockquote><br>It will take a very long time if we start many sheep daemons at the<br>same time? I wonder if we should implement a complete distributed<br>lock based on ZooKeeper recipes:<br><br><a href="http://zookeeper.apache.org/doc/trunk/recipes.html#sc_recipes_Locks">http://zookeeper.apache.org/doc/trunk/recipes.html#sc_recipes_Locks</a><br><br></blockquote><br style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none; ">I think this is a better choice.</span></blockquote></div><br><div><br></div><div>On the second thought, as I browse the code in zookeeper recipes, I think the</div><div>code is not strong enough.</div><div>For example, the lock function is based on creating sequence znode. However,</div><div>if error occurs during the creation, it is not easy to retry it. And the code in</div><div>the recipes didn't handle it at all.</div><div>(The code I found is in version 3.4.5, seems the logic in the code is not same as </div><div>described in the website).</div><div><br></div><div>I would suggest that we use a little number for sleeping, e.g. 50ms.</div><div>And check the existence before creating the lock znode.</div><div>(checking existence is much cheeper than creating)</div><div><br></div><div>This may be simple but not the best choice. </div><div>If it is a big issue in production, I think we can make it better later in other way.</div><div><br></div><div>Thanks,</div><div>Kyle</div></body></html>