You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ar...@apache.org on 2022/05/07 07:52:30 UTC

svn commit: r54311 [1/11] - in /dev/zookeeper/zookeeper-3.7.1-rc1: ./ website/ website/images/ website/skin/

Author: arshad
Date: Sat May  7 07:52:30 2022
New Revision: 54311

Log:
Add ZooKeeper 3.7.1 release candidate 1

Added:
    dev/zookeeper/zookeeper-3.7.1-rc1/
    dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.asc
    dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.sha512
    dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.asc
    dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.sha512
    dev/zookeeper/zookeeper-3.7.1-rc1/website/
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/2pc.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/bk-overview.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/favicon.ico   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/state_dia.dia   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/state_dia.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkAuditLogs.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkarch.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkcomponents.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zknamespace.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfRW-3.2.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfRW.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfreliability.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkservice.jpg   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zookeeper_small.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/index.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/javaExample.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/recipes.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/releasenotes.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/basic.css
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/chapter.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/chapter_open.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/current.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/getBlank.js
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/getMenu.js
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/header_white_line.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/init.js
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/instruction_arrow.png   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/menu.js
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/page.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/print.css
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/printer.gif   (with props)
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/profile.css
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/prototype.js
    dev/zookeeper/zookeeper-3.7.1-rc1/website/skin/screen.css
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperAdmin.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperAuditLogs.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperCLI.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperHierarchicalQuorums.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperInternals.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperJMX.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperMonitor.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperObservers.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperOver.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperProgrammers.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperQuotas.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperReconfig.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperStarted.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperTools.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperTutorial.html
    dev/zookeeper/zookeeper-3.7.1-rc1/website/zookeeperUseCases.html

Added: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.asc
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.asc (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.asc Sat May  7 07:52:30 2022
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCgAdFiEE3/JPuDI62skOPPNvcp5hIw6pF+kFAmJ2FdoACgkQcp5hIw6p
+F+kETRAAuDWRsvOvh+rg9ZfHNlCHlnO9GVnM4QskyPZ3Upo4nkeL5mxuK4zz3bZO
+4LUBvtq29RXmi8Z+rY/truQ4bKXsM5Gd3BL4Je8uFC2dMWf+bnEgvlqQf5eRfDbK
+a0rfw8OwzEkER6zjg9cvPo2dOG5DVrg/84KG+xS+k1bMhut18I4KA5NZUCWsczVc
+jA9E7feI0kDSuw8KNLrA4OMIDDWG/1+CHPrF+cB7jclQEk5W+nUtqAlMJgVF7H19
+dNPIWbBcxAAaL3spUqY1MTZFeJgrh+uzOeq4YaNMgGLPo0WXuKNxv2OAW539DWZB
+1TIShjIoBfpCfuuvXVADIEblwT9G7OYO1t5WF/iNm1C9UY4oxp6ez6o3Sa+YZad8
+iRIzgXbi6AR4HD3vsBlp2XMr+zyXqfXxdKwclp8JqsdB/38tAG0vAN3F0iCo00nJ
+o+/Rgx8oZYcl2UlnvNwJ2xmDEFRhiLzGAOycvWnMLjIqOk+ZayPd1e8Dke8XzgPE
+/cRxmFq8+cMWO4ZqEpLB+/zQX3YiWispjeycpHK81UEhm4fuypqd2MEoCjIe6g1b
+kCzYcfG350spnO2v02tFfMMwQLeqS4Gwuxpogp20pamEIe9QgbG/3W8dzfFw/4I9
+EenIVigCFbLZLQYY7b6Ppffgr4jtMx8OfxyS/AGXzTMluDZQ8nw=
+=ivsT
+-----END PGP SIGNATURE-----

Added: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.sha512
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.sha512 (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1-bin.tar.gz.sha512 Sat May  7 07:52:30 2022
@@ -0,0 +1 @@
+9103628a50745fa1a289bca666fda4a9c08ec17c55cf13e66887e7ba76e93dbae60a1f1ffd6c10798be3a16069344ecbc00cebb29bf03d9cd7096ccd098ed011  apache-zookeeper-3.7.1-bin.tar.gz
\ No newline at end of file

Added: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.asc
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.asc (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.asc Sat May  7 07:52:30 2022
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCgAdFiEE3/JPuDI62skOPPNvcp5hIw6pF+kFAmJ2FWQACgkQcp5hIw6p
+F+ma0hAAw/Ik+MxEnhO9oqiaMW0VZXO2WCvQph6gwgPPq7olV9o9UD8BYTSfrN1o
+YWfhx8z2GtFqbfkwncdL8g7sqoCz2PCNIPMLs0AQ+od51rGbUUHhf3Q+z5PhTk5K
+UrsvoF3/uFjpFLb9pO8TmSE+BjquEyuCv8XSpIpiBFhIbwVdsRCOASufmmiCXcCk
+u5m7gHrUhm/CpbHKZJZpg+Pz88XMY55lKXHvG4ns/ZEjDn7Heec9KXFSLIZ2AQP4
+Pnkmv3S1rdrLS3fDJCQeRJRssZMp0YDkRCTsLr/uYzM2jw0Q/UG1klC0fKXbZY1S
+KO9PoTt3dbpPGPCaT5Bk7ZoOXiGzTqokouMBfL2pRC9hzq3NzN9bESmMvjjIMULl
+A5DV67EhJX2WntwbUo4GTQoPJCXL68mezRKEn+hnuryT2I+o3jNLuDAcK3CcP9Tk
+PyfITDRJ6PcW4i7UXP204WtNC2NHe4oPLrJ8QLXis0WNm2V3S3AetrTjuR4xxQ/F
+zAJAkdpQMJssFBPhWcHzXgz6NzrvsWc65t0zNmD2o1rLx7y1TTMXr+Ny2ZrAbAbe
+fr0WF9IzrgDmr7GhShDx3s0PEZ8SBgTeCaUfjEYQTgB1g+xOf/r58RKE1rhrNZRQ
+roock4N5Vy4yOKEHxvJA84OGaEbhNyzl2RzRu1s3CwQluy0bauA=
+=UMn1
+-----END PGP SIGNATURE-----

Added: dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.sha512
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.sha512 (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/apache-zookeeper-3.7.1.tar.gz.sha512 Sat May  7 07:52:30 2022
@@ -0,0 +1 @@
+b6d61b013bdf7beb916214167de1b55865e5e463b3b5cac84df97fe044227ab03349a0ef4e657149be7cda161039d069c70d90ad56c87674e6dff5ede227de72  apache-zookeeper-3.7.1.tar.gz
\ No newline at end of file

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/2pc.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/2pc.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/bk-overview.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/bk-overview.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/favicon.ico
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/favicon.ico
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/state_dia.dia
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/state_dia.dia
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/state_dia.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/state_dia.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkAuditLogs.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkAuditLogs.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkarch.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkarch.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkcomponents.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkcomponents.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zknamespace.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zknamespace.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfRW-3.2.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfRW-3.2.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfRW.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfRW.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfreliability.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkperfreliability.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkservice.jpg
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zkservice.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zookeeper_small.gif
==============================================================================
Binary file - no diff available.

Propchange: dev/zookeeper/zookeeper-3.7.1-rc1/website/images/zookeeper_small.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/index.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/website/index.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/website/index.html Sat May  7 07:52:30 2022
@@ -0,0 +1,223 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://zookeeper.apache.org/">ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/"><img class="logoImage" alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search" method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" href="http://zookeeper.apache.org/">Project</a>
+            </li>
+            <li>
+                <a class="unselected" href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/">Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+			<div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER">Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ">FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a href="http://zookeeper.apache.org/mailing_lists.html">Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h2>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</h2>
+<p>ZooKeeper is a high-performance coordination service for distributed applications.  It exposes common services - such as naming, configuration management, synchronization, and group services - in a simple interface so you don't have to write them from scratch.  You can use it off-the-shelf to implement consensus, group management, leader election, and presence protocols. And you can build on it for your own, specific needs.</p>
+<p>The following documents describe concepts and procedures to get you started using ZooKeeper. If you have more questions, please ask the <a href="http://zookeeper.apache.org/mailing_lists.html">mailing list</a> or browse the archives.</p>
+<ul>
+<li><strong>ZooKeeper Overview</strong> Technical Overview Documents for Client Developers, Administrators, and Contributors
+<ul>
+<li><a href="zookeeperOver.html">Overview</a> - a bird's eye view of ZooKeeper, including design concepts and architecture</li>
+<li><a href="zookeeperStarted.html">Getting Started</a> - a tutorial-style guide for developers to install, run, and program to ZooKeeper</li>
+<li><a href="releasenotes.html">Release Notes</a> - new developer and user facing features, improvements, and incompatibilities</li>
+</ul>
+</li>
+<li><strong>Developers</strong> Documents for Developers using the ZooKeeper Client API
+<ul>
+<li><a href="apidocs/zookeeper-server/index.html">API Docs</a> - the technical reference to ZooKeeper Client APIs</li>
+<li><a href="zookeeperProgrammers.html">Programmer's Guide</a> - a client application developer's guide to ZooKeeper</li>
+<li><a href="zookeeperUseCases.html">ZooKeeper Use Cases</a> - a series of use cases using the ZooKeeper.</li>
+<li><a href="javaExample.html">ZooKeeper Java Example</a> - a simple Zookeeper client application, written in Java</li>
+<li><a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a> - sample implementations of barriers and queues</li>
+<li><a href="recipes.html">ZooKeeper Recipes</a> - higher level solutions to common problems in distributed applications</li>
+</ul>
+</li>
+<li><strong>Administrators &amp; Operators</strong> Documents for Administrators and Operations Engineers of ZooKeeper Deployments
+<ul>
+<li><a href="zookeeperAdmin.html">Administrator's Guide</a> - a guide for system administrators and anyone else who might deploy ZooKeeper</li>
+<li><a href="zookeeperQuotas.html">Quota Guide</a> - a guide for system administrators on Quotas in ZooKeeper.</li>
+<li><a href="zookeeperJMX.html">JMX</a> - how to enable JMX in ZooKeeper</li>
+<li><a href="zookeeperHierarchicalQuorums.html">Hierarchical Quorums</a> - a guide on how to use hierarchical quorums</li>
+<li><a href="zookeeperObservers.html">Observers</a> - non-voting ensemble members that easily improve ZooKeeper's scalability</li>
+<li><a href="zookeeperReconfig.html">Dynamic Reconfiguration</a> - a guide on how to use dynamic reconfiguration in ZooKeeper</li>
+<li><a href="zookeeperCLI.html">ZooKeeper CLI</a> - a guide on how to use the ZooKeeper command line interface</li>
+<li><a href="zookeeperTools.html">ZooKeeper Tools</a> - a guide on how to use a series of tools for ZooKeeper</li>
+<li><a href="zookeeperMonitor.html">ZooKeeper Monitor</a> - a guide on how to monitor the ZooKeeper</li>
+<li><a href="zookeeperAuditLogs.html">Audit Logging</a> - a guide on how to configure audit logs in ZooKeeper Server and what contents are logged.</li>
+</ul>
+</li>
+<li><strong>Contributors</strong> Documents for Developers Contributing to the ZooKeeper Open Source Project
+<ul>
+<li><a href="zookeeperInternals.html">ZooKeeper Internals</a> - assorted topics on the inner workings of ZooKeeper</li>
+</ul>
+</li>
+<li><strong>Miscellaneous ZooKeeper Documentation</strong>
+<ul>
+<li><a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER">Wiki</a></li>
+<li><a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ">FAQ</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/javaExample.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/website/javaExample.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/website/javaExample.html Sat May  7 07:52:30 2022
@@ -0,0 +1,687 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://zookeeper.apache.org/">ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/"><img class="logoImage" alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search" method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" href="http://zookeeper.apache.org/">Project</a>
+            </li>
+            <li>
+                <a class="unselected" href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/">Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+			<div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER">Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ">FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a href="http://zookeeper.apache.org/mailing_lists.html">Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h1>ZooKeeper Java Example</h1>
+<ul>
+<li><a href="#ch_Introduction">A Simple Watch Client</a>
+<ul>
+<li><a href="#sc_requirements">Requirements</a></li>
+<li><a href="#sc_design">Program Design</a></li>
+</ul>
+</li>
+<li><a href="#sc_executor">The Executor Class</a></li>
+<li><a href="#sc_DataMonitor">The DataMonitor Class</a></li>
+<li><a href="#sc_completeSourceCode">Complete Source Listings</a></li>
+</ul>
+<p><a name="ch_Introduction"></a></p>
+<h2>A Simple Watch Client</h2>
+<p>To introduce you to the ZooKeeper Java API, we develop here a very simple watch client. This ZooKeeper client watches a znode for changes and responds to by starting or stopping a program.</p>
+<p><a name="sc_requirements"></a></p>
+<h3>Requirements</h3>
+<p>The client has four requirements:</p>
+<ul>
+<li>It takes as parameters:</li>
+<li>the address of the ZooKeeper service</li>
+<li>the name of a znode - the one to be watched</li>
+<li>the name of a file to write the output to</li>
+<li>an executable with arguments.</li>
+<li>It fetches the data associated with the znode and starts the executable.</li>
+<li>If the znode changes, the client re-fetches the contents and restarts the executable.</li>
+<li>If the znode disappears, the client kills the executable.</li>
+</ul>
+<p><a name="sc_design"></a></p>
+<h3>Program Design</h3>
+<p>Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, and the other which monitors data.  In this application, the class called the <strong>Executor</strong> maintains the ZooKeeper connection, and the class called the <strong>DataMonitor</strong> monitors the data in the ZooKeeper tree. Also, Executor contains the main thread and contains the execution logic. It is responsible for what little user interaction there is, as well as interaction with the executable program you pass in as an argument and which the sample (per the requirements) shuts down and restarts, according to the state of the znode.</p>
+<p><a name="sc_executor"></a></p>
+<h2>The Executor Class</h2>
+<p>The Executor object is the primary container of the sample application. It contains both the <strong>ZooKeeper</strong> object, <strong>DataMonitor</strong>, as described above in <a href="#sc_design">Program Design</a>.</p>
+<pre><code>// from the Executor class...
+
+public static void main(String[] args) {
+    if (args.length &lt; 4) {
+        System.err
+                .println(&quot;USAGE: Executor hostPort znode filename program [args ...]&quot;);
+        System.exit(2);
+    }
+    String hostPort = args[0];
+    String znode = args[1];
+    String filename = args[2];
+    String exec[] = new String[args.length - 3];
+    System.arraycopy(args, 3, exec, 0, exec.length);
+    try {
+        new Executor(hostPort, znode, filename, exec).run();
+    } catch (Exception e) {
+        e.printStackTrace();
+    }
+}
+
+public Executor(String hostPort, String znode, String filename,
+        String exec[]) throws KeeperException, IOException {
+    this.filename = filename;
+    this.exec = exec;
+    zk = new ZooKeeper(hostPort, 3000, this);
+    dm = new DataMonitor(zk, znode, null, this);
+}
+
+public void run() {
+    try {
+        synchronized (this) {
+            while (!dm.dead) {
+                wait();
+            }
+        }
+    } catch (InterruptedException e) {
+    }
+}
+</code></pre>
+<p>Recall that the Executor's job is to start and stop the executable whose name you pass in on the command line. It does this in response to events fired by the ZooKeeper object. As you can see in the code above, the Executor passes a reference to itself as the Watcher argument in the ZooKeeper constructor. It also passes a reference to itself as DataMonitorListener argument to the DataMonitor constructor. Per the Executor's definition, it implements both these interfaces:</p>
+<pre><code>public class Executor implements Watcher, Runnable, DataMonitor.DataMonitorListener {
+...
+</code></pre>
+<p>The <strong>Watcher</strong> interface is defined by the ZooKeeper Java API. ZooKeeper uses it to communicate back to its container. It supports only one method, <code>process()</code>, and ZooKeeper uses it to communicates generic events that the main thread would be interested in, such as the state of the ZooKeeper connection or the ZooKeeper session. The Executor in this example simply forwards those events down to the DataMonitor to decide what to do with them. It does this simply to illustrate the point that, by convention, the Executor or some Executor-like object &quot;owns&quot; the ZooKeeper connection, but it is free to delegate the events to other events to other objects. It also uses this as the default channel on which to fire watch events. (More on this later.)</p>
+<pre><code>public void process(WatchedEvent event) {
+    dm.process(event);
+}
+</code></pre>
+<p>The <strong>DataMonitorListener</strong> interface, on the other hand, is not part of the ZooKeeper API. It is a completely custom interface, designed for this sample application. The DataMonitor object uses it to communicate back to its container, which is also the Executor object. The DataMonitorListener interface looks like this:</p>
+<pre><code>public interface DataMonitorListener {
+    /**
+    * The existence status of the node has changed.
+    */
+    void exists(byte data[]);
+
+    /**
+    * The ZooKeeper session is no longer valid.
+    *
+    * @param rc
+    * the ZooKeeper reason code
+    */
+    void closing(int rc);
+}
+</code></pre>
+<p>This interface is defined in the DataMonitor class and implemented in the Executor class. When <code>Executor.exists()</code> is invoked, the Executor decides whether to start up or shut down per the requirements. Recall that the requires say to kill the executable when the znode ceases to <em>exist</em>.</p>
+<p>When <code>Executor.closing()</code> is invoked, the Executor decides whether or not to shut itself down in response to the ZooKeeper connection permanently disappearing.</p>
+<p>As you might have guessed, DataMonitor is the object that invokes these methods, in response to changes in ZooKeeper's state.</p>
+<p>Here are Executor's implementation of <code>DataMonitorListener.exists()</code> and <code>DataMonitorListener.closing</code>:</p>
+<pre><code>public void exists( byte[] data ) {
+    if (data == null) {
+        if (child != null) {
+            System.out.println(&quot;Killing process&quot;);
+            child.destroy();
+            try {
+                child.waitFor();
+            } catch (InterruptedException e) {
+           }
+        }
+        child = null;
+    } else {
+        if (child != null) {
+            System.out.println(&quot;Stopping child&quot;);
+            child.destroy();
+            try {
+               child.waitFor();
+            } catch (InterruptedException e) {
+            e.printStackTrace();
+            }
+        }
+        try {
+            FileOutputStream fos = new FileOutputStream(filename);
+            fos.write(data);
+            fos.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            System.out.println(&quot;Starting child&quot;);
+            child = Runtime.getRuntime().exec(exec);
+            new StreamWriter(child.getInputStream(), System.out);
+            new StreamWriter(child.getErrorStream(), System.err);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
+
+public void closing(int rc) {
+    synchronized (this) {
+        notifyAll();
+    }
+}
+</code></pre>
+<p><a name="sc_DataMonitor"></a></p>
+<h2>The DataMonitor Class</h2>
+<p>The DataMonitor class has the meat of the ZooKeeper logic. It is mostly asynchronous and event driven. DataMonitor kicks things off in the constructor with:</p>
+<pre><code>public DataMonitor(ZooKeeper zk, String znode, Watcher chainedWatcher,
+        DataMonitorListener listener) {
+    this.zk = zk;
+    this.znode = znode;
+    this.chainedWatcher = chainedWatcher;
+    this.listener = listener;
+
+    // Get things started by checking if the node exists. We are going
+    // to be completely event driven
+</code></pre>
+<p>The call to <code>ZooKeeper.exists()</code> checks for the existence of the znode, sets a watch, and passes a reference to itself (<code>this</code>) as the completion callback object. In this sense, it kicks things off, since the real processing happens when the watch is triggered.</p>
+<h6>Note</h6>
+<blockquote>
+<p>Don't confuse the completion callback with the watch callback. The <code>ZooKeeper.exists()</code> completion callback, which happens to be the method <code>StatCallback.processResult()</code> implemented in the DataMonitor object, is invoked when the asynchronous <em>setting of the watch</em> operation (by <code>ZooKeeper.exists()</code>) completes on the server.</p>
+<p>The triggering of the watch, on the other hand, sends an event to the <em>Executor</em> object, since the Executor registered as the Watcher of the ZooKeeper object.</p>
+<p>As an aside, you might note that the DataMonitor could also register itself as the Watcher for this particular watch event. This is new to ZooKeeper 3.0.0 (the support of multiple Watchers). In this example, however, DataMonitor does not register as the Watcher.</p>
+</blockquote>
+<p>When the <code>ZooKeeper.exists()</code> operation completes on the server, the ZooKeeper API invokes this completion callback on the client:</p>
+<pre><code>public void processResult(int rc, String path, Object ctx, Stat stat) {
+    boolean exists;
+    switch (rc) {
+    case Code.Ok:
+        exists = true;
+        break;
+    case Code.NoNode:
+        exists = false;
+        break;
+    case Code.SessionExpired:
+    case Code.NoAuth:
+        dead = true;
+        listener.closing(rc);
+        return;
+    default:
+        // Retry errors
+        zk.exists(znode, true, this, null);
+        return;
+    }
+
+    byte b[] = null;
+    if (exists) {
+        try {
+            b = zk.getData(znode, false, null);
+        } catch (KeeperException e) {
+            // We don't need to worry about recovering now. The watch
+            // callbacks will kick off any exception handling
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            return;
+        }
+    }     
+    if ((b == null &amp;amp;&amp;amp; b != prevData)
+        || (b != null &amp;amp;&amp;amp; !Arrays.equals(prevData, b))) {
+        listener.exists(b);&lt;/emphasis&gt;
+        prevData = b;
+    }
+}
+</code></pre>
+<p>The code first checks the error codes for znode existence, fatal errors, and recoverable errors. If the file (or znode) exists, it gets the data from the znode, and then invoke the exists() callback of Executor if the state has changed. Note, it doesn't have to do any Exception processing for the getData call because it has watches pending for anything that could cause an error: if the node is deleted before it calls <code>ZooKeeper.getData()</code>, the watch event set by the <code>ZooKeeper.exists()</code> triggers a callback; if there is a communication error, a connection watch event fires when the connection comes back up.</p>
+<p>Finally, notice how DataMonitor processes watch events:</p>
+<pre><code>public void process(WatchedEvent event) {
+    String path = event.getPath();
+    if (event.getType() == Event.EventType.None) {
+        // We are are being told that the state of the
+        // connection has changed
+        switch (event.getState()) {
+        case SyncConnected:
+            // In this particular example we don't need to do anything
+            // here - watches are automatically re-registered with
+            // server and any watches triggered while the client was
+            // disconnected will be delivered (in order of course)
+            break;
+        case Expired:
+            // It's all over
+            dead = true;
+            listener.closing(KeeperException.Code.SessionExpired);
+            break;
+        }
+    } else {
+        if (path != null &amp;&amp; path.equals(znode)) {
+            // Something has changed on the node, let's find out
+            zk.exists(znode, true, this, null);
+        }
+    }
+    if (chainedWatcher != null) {
+        chainedWatcher.process(event);
+    }
+}
+</code></pre>
+<p>If the client-side ZooKeeper libraries can re-establish the communication channel (SyncConnected event) to ZooKeeper before session expiration (Expired event) all of the session's watches will automatically be re-established with the server (auto-reset of watches is new in ZooKeeper 3.0.0). See <a href="zookeeperProgrammers.html#ch_zkWatches">ZooKeeper Watches</a> in the programmer guide for more on this. A bit lower down in this function, when DataMonitor gets an event for a znode, it calls<code>ZooKeeper.exists()</code> to find out what has changed.</p>
+<p><a name="sc_completeSourceCode"></a></p>
+<h2>Complete Source Listings</h2>
+<h3>Executor.java</h3>
+<pre><code>/**
+ * A simple example program to use DataMonitor to start and
+ * stop executables based on a znode. The program watches the
+ * specified znode and saves the data that corresponds to the
+ * znode in the filesystem. It also starts the specified program
+ * with the specified arguments when the znode exists and kills
+ * the program if the znode goes away.
+ */
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+
+public class Executor
+    implements Watcher, Runnable, DataMonitor.DataMonitorListener
+{
+    String znode;
+    DataMonitor dm;
+    ZooKeeper zk;
+    String filename;
+    String exec[];
+    Process child;
+
+    public Executor(String hostPort, String znode, String filename,
+            String exec[]) throws KeeperException, IOException {
+        this.filename = filename;
+        this.exec = exec;
+        zk = new ZooKeeper(hostPort, 3000, this);
+        dm = new DataMonitor(zk, znode, null, this);
+    }
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        if (args.length &lt; 4) {
+            System.err
+                    .println(&quot;USAGE: Executor hostPort znode filename program [args ...]&quot;);
+            System.exit(2);
+        }
+        String hostPort = args[0];
+        String znode = args[1];
+        String filename = args[2];
+        String exec[] = new String[args.length - 3];
+        System.arraycopy(args, 3, exec, 0, exec.length);
+        try {
+            new Executor(hostPort, znode, filename, exec).run();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /***************************************************************************
+     * We do process any events ourselves, we just need to forward them on.
+     *
+     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.proto.WatcherEvent)
+     */
+    public void process(WatchedEvent event) {
+        dm.process(event);
+    }
+
+    public void run() {
+        try {
+            synchronized (this) {
+                while (!dm.dead) {
+                    wait();
+                }
+            }
+        } catch (InterruptedException e) {
+        }
+    }
+
+    public void closing(int rc) {
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+
+    static class StreamWriter extends Thread {
+        OutputStream os;
+
+        InputStream is;
+
+        StreamWriter(InputStream is, OutputStream os) {
+            this.is = is;
+            this.os = os;
+            start();
+        }
+
+        public void run() {
+            byte b[] = new byte[80];
+            int rc;
+            try {
+                while ((rc = is.read(b)) &gt; 0) {
+                    os.write(b, 0, rc);
+                }
+            } catch (IOException e) {
+            }
+
+        }
+    }
+
+    public void exists(byte[] data) {
+        if (data == null) {
+            if (child != null) {
+                System.out.println(&quot;Killing process&quot;);
+                child.destroy();
+                try {
+                    child.waitFor();
+                } catch (InterruptedException e) {
+                }
+            }
+            child = null;
+        } else {
+            if (child != null) {
+                System.out.println(&quot;Stopping child&quot;);
+                child.destroy();
+                try {
+                    child.waitFor();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+            try {
+                FileOutputStream fos = new FileOutputStream(filename);
+                fos.write(data);
+                fos.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            try {
+                System.out.println(&quot;Starting child&quot;);
+                child = Runtime.getRuntime().exec(exec);
+                new StreamWriter(child.getInputStream(), System.out);
+                new StreamWriter(child.getErrorStream(), System.err);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
+</code></pre>
+<h3>DataMonitor.java</h3>
+<pre><code>/**
+ * A simple class that monitors the data and existence of a ZooKeeper
+ * node. It uses asynchronous ZooKeeper APIs.
+ */
+import java.util.Arrays;
+
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.data.Stat;
+
+public class DataMonitor implements Watcher, StatCallback {
+
+    ZooKeeper zk;
+    String znode;
+    Watcher chainedWatcher;
+    boolean dead;
+    DataMonitorListener listener;
+    byte prevData[];
+
+    public DataMonitor(ZooKeeper zk, String znode, Watcher chainedWatcher,
+            DataMonitorListener listener) {
+        this.zk = zk;
+        this.znode = znode;
+        this.chainedWatcher = chainedWatcher;
+        this.listener = listener;
+        // Get things started by checking if the node exists. We are going
+        // to be completely event driven
+        zk.exists(znode, true, this, null);
+    }
+
+    /**
+     * Other classes use the DataMonitor by implementing this method
+     */
+    public interface DataMonitorListener {
+        /**
+         * The existence status of the node has changed.
+         */
+        void exists(byte data[]);
+
+        /**
+         * The ZooKeeper session is no longer valid.
+         *
+         * @param rc
+         *                the ZooKeeper reason code
+         */
+        void closing(int rc);
+    }
+
+    public void process(WatchedEvent event) {
+        String path = event.getPath();
+        if (event.getType() == Event.EventType.None) {
+            // We are are being told that the state of the
+            // connection has changed
+            switch (event.getState()) {
+            case SyncConnected:
+                // In this particular example we don't need to do anything
+                // here - watches are automatically re-registered with
+                // server and any watches triggered while the client was
+                // disconnected will be delivered (in order of course)
+                break;
+            case Expired:
+                // It's all over
+                dead = true;
+                listener.closing(KeeperException.Code.SessionExpired);
+                break;
+            }
+        } else {
+            if (path != null &amp;&amp; path.equals(znode)) {
+                // Something has changed on the node, let's find out
+                zk.exists(znode, true, this, null);
+            }
+        }
+        if (chainedWatcher != null) {
+            chainedWatcher.process(event);
+        }
+    }
+
+    public void processResult(int rc, String path, Object ctx, Stat stat) {
+        boolean exists;
+        switch (rc) {
+        case Code.Ok:
+            exists = true;
+            break;
+        case Code.NoNode:
+            exists = false;
+            break;
+        case Code.SessionExpired:
+        case Code.NoAuth:
+            dead = true;
+            listener.closing(rc);
+            return;
+        default:
+            // Retry errors
+            zk.exists(znode, true, this, null);
+            return;
+        }
+
+        byte b[] = null;
+        if (exists) {
+            try {
+                b = zk.getData(znode, false, null);
+            } catch (KeeperException e) {
+                // We don't need to worry about recovering now. The watch
+                // callbacks will kick off any exception handling
+                e.printStackTrace();
+            } catch (InterruptedException e) {
+                return;
+            }
+        }
+        if ((b == null &amp;&amp; b != prevData)
+                || (b != null &amp;&amp; !Arrays.equals(prevData, b))) {
+            listener.exists(b);
+            prevData = b;
+        }
+    }
+}
+</code></pre>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: dev/zookeeper/zookeeper-3.7.1-rc1/website/recipes.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc1/website/recipes.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc1/website/recipes.html Sat May  7 07:52:30 2022
@@ -0,0 +1,353 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/">Apache</a> &gt; <a href="http://zookeeper.apache.org/">ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/"><img class="logoImage" alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search" method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" href="http://zookeeper.apache.org/">Project</a>
+            </li>
+            <li>
+                <a class="unselected" href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/">Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+			<div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER">Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ">FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a href="http://zookeeper.apache.org/mailing_lists.html">Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h1>ZooKeeper Recipes and Solutions</h1>
+<ul>
+<li><a href="#ch_recipes">A Guide to Creating Higher-level Constructs with ZooKeeper</a>
+<ul>
+<li><a href="#sc_recipes_errorHandlingNote">Important Note About Error Handling</a></li>
+<li><a href="#sc_outOfTheBox">Out of the Box Applications: Name Service, Configuration, Group Membership</a></li>
+<li><a href="#sc_recipes_eventHandles">Barriers</a>
+<ul>
+<li><a href="#sc_doubleBarriers">Double Barriers</a></li>
+</ul>
+</li>
+<li><a href="#sc_recipes_Queues">Queues</a>
+<ul>
+<li><a href="#sc_recipes_priorityQueues">Priority Queues</a></li>
+</ul>
+</li>
+<li><a href="#sc_recipes_Locks">Locks</a>
+<ul>
+<li><a href="#sc_recipes_GuidNote">Recoverable Errors and the GUID</a></li>
+<li><a href="#Shared+Locks">Shared Locks</a></li>
+<li><a href="#sc_revocableSharedLocks">Revocable Shared Locks</a></li>
+</ul>
+</li>
+<li><a href="#sc_recipes_twoPhasedCommit">Two-phased Commit</a></li>
+<li><a href="#sc_leaderElection">Leader Election</a></li>
+</ul>
+</li>
+</ul>
+<p><a name="ch_recipes"></a></p>
+<h2>A Guide to Creating Higher-level Constructs with ZooKeeper</h2>
+<p>In this article, you'll find guidelines for using ZooKeeper to implement higher order functions. All of them are conventions implemented at the client and do not require special support from ZooKeeper. Hopefully the community will capture these conventions in client-side libraries to ease their use and to encourage standardization.</p>
+<p>One of the most interesting things about ZooKeeper is that even though ZooKeeper uses <em>asynchronous</em> notifications, you can use it to build <em>synchronous</em> consistency primitives, such as queues and locks. As you will see, this is possible because ZooKeeper imposes an overall order on updates, and has mechanisms to expose this ordering.</p>
+<p>Note that the recipes below attempt to employ best practices. In particular, they avoid polling, timers or anything else that would result in a &quot;herd effect&quot;, causing bursts of traffic and limiting scalability.</p>
+<p>There are many useful functions that can be imagined that aren't included here - revocable read-write priority locks, as just one example. And some of the constructs mentioned here - locks, in particular - illustrate certain points, even though you may find other constructs, such as event handles or queues, a more practical means of performing the same function. In general, the examples in this section are designed to stimulate thought.</p>
+<p><a name="sc_recipes_errorHandlingNote"></a></p>
+<h3>Important Note About Error Handling</h3>
+<p>When implementing the recipes you must handle recoverable exceptions (see the <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ">FAQ</a>). In particular, several of the recipes employ sequential ephemeral nodes. When creating a sequential ephemeral node there is an error case in which the create() succeeds on the server but the server crashes before returning the name of the node to the client. When the client reconnects its session is still valid and, thus, the node is not removed. The implication is that it is difficult for the client to know if its node was created or not. The recipes below include measures to handle this.</p>
+<p><a name="sc_outOfTheBox"></a></p>
+<h3>Out of the Box Applications: Name Service, Configuration, Group Membership</h3>
+<p>Name service and configuration are two of the primary applications of ZooKeeper. These two functions are provided directly by the ZooKeeper API.</p>
+<p>Another function directly provided by ZooKeeper is <em>group membership</em>. The group is represented by a node. Members of the group create ephemeral nodes under the group node. Nodes of the members that fail abnormally will be removed automatically when ZooKeeper detects the failure.</p>
+<p><a name="sc_recipes_eventHandles"></a></p>
+<h3>Barriers</h3>
+<p>Distributed systems use <em>barriers</em> to block processing of a set of nodes until a condition is met at which time all the nodes are allowed to proceed. Barriers are implemented in ZooKeeper by designating a barrier node. The barrier is in place if the barrier node exists. Here's the pseudo code:</p>
+<ol>
+<li>Client calls the ZooKeeper API's <strong>exists()</strong> function on the barrier node, with <em>watch</em> set to true.</li>
+<li>If <strong>exists()</strong> returns false, the barrier is gone and the client proceeds</li>
+<li>Else, if <strong>exists()</strong> returns true, the clients wait for a watch event from ZooKeeper for the barrier node.</li>
+<li>When the watch event is triggered, the client reissues the <strong>exists( )</strong> call, again waiting until the barrier node is removed.</li>
+</ol>
+<p><a name="sc_doubleBarriers"></a></p>
+<h4>Double Barriers</h4>
+<p>Double barriers enable clients to synchronize the beginning and the end of a computation. When enough processes have joined the barrier, processes start their computation and leave the barrier once they have finished. This recipe shows how to use a ZooKeeper node as a barrier.</p>
+<p>The pseudo code in this recipe represents the barrier node as <em>b</em>. Every client process <em>p</em> registers with the barrier node on entry and unregisters when it is ready to leave. A node registers with the barrier node via the <strong>Enter</strong> procedure below, it waits until <em>x</em> client process register before proceeding with the computation. (The <em>x</em> here is up to you to determine for your system.)</p>
+<table>
+<thead>
+<tr><th> <strong>Enter</strong>                         </th><th> <strong>Leave</strong>                     </th></tr>
+</thead>
+<tbody>
+<tr><td> 1. Create a name <em><em>n</em> = <em>b</em>+“/”+<em>p</em></em> </td><td> 1. <strong>L = getChildren(b, false)</strong> </td></tr>
+<tr><td> 2. Set watch: <strong>exists(<em>b</em> + ‘‘/ready’’, true)</strong> </td><td> 2. if no children, exit </td></tr>
+<tr><td> 3. Create child: <strong>create(<em>n</em>, EPHEMERAL)</strong>  </td><td> 3. if <em>p</em> is only process node in L, delete(n) and exit </td></tr>
+<tr><td> 4. <strong>L = getChildren(b, false)</strong>  </td><td> 4. if <em>p</em> is the lowest process node in L, wait on highest process node in L </td></tr>
+<tr><td> 5. if fewer children in L than_x_, wait for watch event  </td><td> 5. else **delete(<em>n</em>)**if still exists and wait on lowest process node in L </td></tr>
+<tr><td> 6. else <strong>create(b + ‘‘/ready’’, REGULAR)</strong> </td><td> 6. goto 1 </td></tr>
+</tbody>
+</table>
+<p>On entering, all processes watch on a ready node and create an ephemeral node as a child of the barrier node. Each process but the last enters the barrier and waits for the ready node to appear at line 5. The process that creates the xth node, the last process, will see x nodes in the list of children and create the ready node, waking up the other processes. Note that waiting processes wake up only when it is time to exit, so waiting is efficient.</p>
+<p>On exit, you can't use a flag such as <em>ready</em> because you are watching for process nodes to go away. By using ephemeral nodes, processes that fail after the barrier has been entered do not prevent correct processes from finishing. When processes are ready to leave, they need to delete their process nodes and wait for all other processes to do the same.</p>
+<p>Processes exit when there are no process nodes left as children of <em>b</em>. However, as an efficiency, you can use the lowest process node as the ready flag. All other processes that are ready to exit watch for the lowest existing process node to go away, and the owner of the lowest process watches for any other process node (picking the highest for simplicity) to go away. This means that only a single process wakes up on each node deletion except for the last node, which wakes up everyone when it is removed.</p>
+<p><a name="sc_recipes_Queues"></a></p>
+<h3>Queues</h3>
+<p>Distributed queues are a common data structure. To implement a distributed queue in ZooKeeper, first designate a znode to hold the queue, the queue node. The distributed clients put something into the queue by calling create() with a pathname ending in &quot;queue-&quot;, with the <em>sequence</em> and <em>ephemeral</em> flags in the create() call set to true. Because the <em>sequence</em> flag is set, the new pathnames will have the form <em>path-to-queue-node</em>/queue-X, where X is a monotonic increasing number. A client that wants to be removed from the queue calls ZooKeeper's <strong>getChildren( )</strong> function, with <em>watch</em> set to true on the queue node, and begins processing nodes with the lowest number. The client does not need to issue another <strong>getChildren( )</strong> until it exhausts the list obtained from the first <strong>getChildren( )</strong> call. If there are are no children in the queue node, the reader waits for a watch notification to chec
 k the queue again.</p>
+<h6>Note</h6>
+<blockquote>
+<p>There now exists a Queue implementation in ZooKeeper recipes directory. This is distributed with the release -- zookeeper-recipes/zookeeper-recipes-queue directory of the release artifact.</p>
+</blockquote>
+<p><a name="sc_recipes_priorityQueues"></a></p>
+<h4>Priority Queues</h4>
+<p>To implement a priority queue, you need only make two simple changes to the generic <a href="#sc_recipes_Queues">queue recipe</a> . First, to add to a queue, the pathname ends with &quot;queue-YY&quot; where YY is the priority of the element with lower numbers representing higher priority (just like UNIX). Second, when removing from the queue, a client uses an up-to-date children list meaning that the client will invalidate previously obtained children lists if a watch notification triggers for the queue node.</p>
+<p><a name="sc_recipes_Locks"></a></p>
+<h3>Locks</h3>
+<p>Fully distributed locks that are globally synchronous, meaning at any snapshot in time no two clients think they hold the same lock. These can be implemented using ZooKeeeper. As with priority queues, first define a lock node.</p>
+<h6>Note</h6>
+<blockquote>
+<p>There now exists a Lock implementation in ZooKeeper recipes directory. This is distributed with the release -- zookeeper-recipes/zookeeper-recipes-lock directory of the release artifact.</p>
+</blockquote>
+<p>Clients wishing to obtain a lock do the following:</p>
+<ol>
+<li>Call <strong>create( )</strong> with a pathname of &quot;<em>locknode</em>/guid-lock-&quot; and the <em>sequence</em> and <em>ephemeral</em> flags set. The <em>guid</em> is needed in case the create() result is missed. See the note below.</li>
+<li>Call <strong>getChildren( )</strong> on the lock node <em>without</em> setting the watch flag (this is important to avoid the herd effect).</li>
+<li>If the pathname created in step <strong>1</strong> has the lowest sequence number suffix, the client has the lock and the client exits the protocol.</li>
+<li>The client calls <strong>exists( )</strong> with the watch flag set on the path in the lock directory with the next lowest sequence number.</li>
+<li>if <strong>exists( )</strong> returns null, go to step <strong>2</strong>. Otherwise, wait for a notification for the pathname from the previous step before going to step <strong>2</strong>.</li>
+</ol>
+<p>The unlock protocol is very simple: clients wishing to release a lock simply delete the node they created in step 1.</p>
+<p>Here are a few things to notice:</p>
+<ul>
+<li>
+<p>The removal of a node will only cause one client to wake up since each node is watched by exactly one client. In this way, you avoid the herd effect.</p>
+</li>
+<li>
+<p>There is no polling or timeouts.</p>
+</li>
+<li>
+<p>Because of the way you implement locking, it is easy to see the amount of lock contention, break locks, debug locking problems, etc.</p>
+</li>
+</ul>
+<p><a name="sc_recipes_GuidNote"></a></p>
+<h4>Recoverable Errors and the GUID</h4>
+<ul>
+<li>If a recoverable error occurs calling <strong>create()</strong> the client should call <strong>getChildren()</strong> and check for a node containing the <em>guid</em> used in the path name. This handles the case (noted <a href="#sc_recipes_errorHandlingNote">above</a>) of the create() succeeding on the server but the server crashing before returning the name of the new node.</li>
+</ul>
+<p><a name="Shared+Locks"></a></p>
+<h4>Shared Locks</h4>
+<p>You can implement shared locks by with a few changes to the lock protocol:</p>
+<table>
+<thead>
+<tr><th> <strong>Obtaining a read lock:</strong> </th><th> <strong>Obtaining a write lock:</strong> </th></tr>
+</thead>
+<tbody>
+<tr><td> 1. Call <strong>create( )</strong> to create a node with pathname &quot;<em>guid-/read-</em>&quot;. This is the lock node use later in the protocol. Make sure to set both the <em>sequence</em> and <em>ephemeral</em> flags. </td><td> 1. Call <strong>create( )</strong> to create a node with pathname &quot;<em>guid-/write-</em>&quot;. This is the lock node spoken of later in the protocol. Make sure to set both <em>sequence</em> and <em>ephemeral</em> flags. </td></tr>
+<tr><td> 2. Call <strong>getChildren( )</strong> on the lock node <em>without</em> setting the <em>watch</em> flag - this is important, as it avoids the herd effect. </td><td> 2. Call <strong>getChildren( )</strong> on the lock node <em>without</em> setting the <em>watch</em> flag - this is important, as it avoids the herd effect. </td></tr>
+<tr><td> 3. If there are no children with a pathname starting with &quot;<em>write-</em>&quot; and having a lower sequence number than the node created in step <strong>1</strong>, the client has the lock and can exit the protocol. </td><td> 3. If there are no children with a lower sequence number than the node created in step <strong>1</strong>, the client has the lock and the client exits the protocol. </td></tr>
+<tr><td> 4. Otherwise, call <strong>exists( )</strong>, with <em>watch</em> flag, set on the node in lock directory with pathname starting with &quot;<em>write-</em>&quot; having the next lowest sequence number. </td><td> 4. Call <strong>exists( ),</strong> with <em>watch</em> flag set, on the node with the pathname that has the next lowest sequence number. </td></tr>
+<tr><td> 5. If <strong>exists( )</strong> returns <em>false</em>, goto step <strong>2</strong>. </td><td> 5. If <strong>exists( )</strong> returns <em>false</em>, goto step <strong>2</strong>. Otherwise, wait for a notification for the pathname from the previous step before going to step <strong>2</strong>. </td></tr>
+<tr><td> 6. Otherwise, wait for a notification for the pathname from the previous step before going to step <strong>2</strong> </td><td>  </td></tr>
+</tbody>
+</table>
+<p>Notes:</p>
+<ul>
+<li>
+<p>It might appear that this recipe creates a herd effect: when there is a large group of clients waiting for a read lock, and all getting notified more or less simultaneously when the &quot;<em>write-</em>&quot; node with the lowest sequence number is deleted. In fact. that's valid behavior: as all those waiting reader clients should be released since they have the lock. The herd effect refers to releasing a &quot;herd&quot; when in fact only a single or a small number of machines can proceed.</p>
+</li>
+<li>
+<p>See the <a href="#sc_recipes_GuidNote">note for Locks</a> on how to use the guid in the node.</p>
+</li>
+</ul>
+<p><a name="sc_revocableSharedLocks"></a></p>
+<h4>Revocable Shared Locks</h4>
+<p>With minor modifications to the Shared Lock protocol, you make shared locks revocable by modifying the shared lock protocol:</p>
+<p>In step <strong>1</strong>, of both obtain reader and writer lock protocols, call <strong>getData( )</strong> with <em>watch</em> set, immediately after the call to <strong>create( )</strong>. If the client subsequently receives notification for the node it created in step <strong>1</strong>, it does another <strong>getData( )</strong> on that node, with <em>watch</em> set and looks for the string &quot;unlock&quot;, which signals to the client that it must release the lock. This is because, according to this shared lock protocol, you can request the client with the lock give up the lock by calling <strong>setData()</strong> on the lock node, writing &quot;unlock&quot; to that node.</p>
+<p>Note that this protocol requires the lock holder to consent to releasing the lock. Such consent is important, especially if the lock holder needs to do some processing before releasing the lock. Of course you can always implement <em>Revocable Shared Locks with Freaking Laser Beams</em> by stipulating in your protocol that the revoker is allowed to delete the lock node if after some length of time the lock isn't deleted by the lock holder.</p>
+<p><a name="sc_recipes_twoPhasedCommit"></a></p>
+<h3>Two-phased Commit</h3>
+<p>A two-phase commit protocol is an algorithm that lets all clients in a distributed system agree either to commit a transaction or abort.</p>
+<p>In ZooKeeper, you can implement a two-phased commit by having a coordinator create a transaction node, say &quot;/app/Tx&quot;, and one child node per participating site, say &quot;/app/Tx/s_i&quot;. When coordinator creates the child node, it leaves the content undefined. Once each site involved in the transaction receives the transaction from the coordinator, the site reads each child node and sets a watch. Each site then processes the query and votes &quot;commit&quot; or &quot;abort&quot; by writing to its respective node. Once the write completes, the other sites are notified, and as soon as all sites have all votes, they can decide either &quot;abort&quot; or &quot;commit&quot;. Note that a node can decide &quot;abort&quot; earlier if some site votes for &quot;abort&quot;.</p>
+<p>An interesting aspect of this implementation is that the only role of the coordinator is to decide upon the group of sites, to create the ZooKeeper nodes, and to propagate the transaction to the corresponding sites. In fact, even propagating the transaction can be done through ZooKeeper by writing it in the transaction node.</p>
+<p>There are two important drawbacks of the approach described above. One is the message complexity, which is O(n²). The second is the impossibility of detecting failures of sites through ephemeral nodes. To detect the failure of a site using ephemeral nodes, it is necessary that the site create the node.</p>
+<p>To solve the first problem, you can have only the coordinator notified of changes to the transaction nodes, and then notify the sites once coordinator reaches a decision. Note that this approach is scalable, but it's is slower too, as it requires all communication to go through the coordinator.</p>
+<p>To address the second problem, you can have the coordinator propagate the transaction to the sites, and have each site creating its own ephemeral node.</p>
+<p><a name="sc_leaderElection"></a></p>
+<h3>Leader Election</h3>
+<p>A simple way of doing leader election with ZooKeeper is to use the <strong>SEQUENCE|EPHEMERAL</strong> flags when creating znodes that represent &quot;proposals&quot; of clients. The idea is to have a znode, say &quot;/election&quot;, such that each znode creates a child znode &quot;/election/guid-n_&quot; with both flags SEQUENCE|EPHEMERAL. With the sequence flag, ZooKeeper automatically appends a sequence number that is greater than any one previously appended to a child of &quot;/election&quot;. The process that created the znode with the smallest appended sequence number is the leader.</p>
+<p>That's not all, though. It is important to watch for failures of the leader, so that a new client arises as the new leader in the case the current leader fails. A trivial solution is to have all application processes watching upon the current smallest znode, and checking if they are the new leader when the smallest znode goes away (note that the smallest znode will go away if the leader fails because the node is ephemeral). But this causes a herd effect: upon a failure of the current leader, all other processes receive a notification, and execute getChildren on &quot;/election&quot; to obtain the current list of children of &quot;/election&quot;. If the number of clients is large, it causes a spike on the number of operations that ZooKeeper servers have to process. To avoid the herd effect, it is sufficient to watch for the next znode down on the sequence of znodes. If a client receives a notification that the znode it is watching is gone, then it becomes the new leader in the ca
 se that there is no smaller znode. Note that this avoids the herd effect by not having all clients watching the same znode.</p>
+<p>Here's the pseudo code:</p>
+<p>Let ELECTION be a path of choice of the application. To volunteer to be a leader:</p>
+<ol>
+<li>Create znode z with path &quot;ELECTION/guid-n_&quot; with both SEQUENCE and EPHEMERAL flags;</li>
+<li>Let C be the children of &quot;ELECTION&quot;, and i be the sequence number of z;</li>
+<li>Watch for changes on &quot;ELECTION/guid-n_j&quot;, where j is the largest sequence number such that j &lt; i and n_j is a znode in C;</li>
+</ol>
+<p>Upon receiving a notification of znode deletion:</p>
+<ol>
+<li>Let C be the new set of children of ELECTION;</li>
+<li>If z is the smallest node in C, then execute leader procedure;</li>
+<li>Otherwise, watch for changes on &quot;ELECTION/guid-n_j&quot;, where j is the largest sequence number such that j &lt; i and n_j is a znode in C;</li>
+</ol>
+<p>Notes:</p>
+<ul>
+<li>
+<p>Note that the znode having no preceding znode on the list of children do not imply that the creator of this znode is aware that it is the current leader. Applications may consider creating a separate znode to acknowledge that the leader has executed the leader procedure.</p>
+</li>
+<li>
+<p>See the <a href="#sc_recipes_GuidNote">note for Locks</a> on how to use the guid in the node.</p>
+</li>
+</ul>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file