You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2013/03/27 02:11:12 UTC

[17/52] [abbrv] git commit: site wip

site wip


Project: http://git-wip-us.apache.org/repos/asf/incubator-curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-curator/commit/197a6d6a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-curator/tree/197a6d6a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-curator/diff/197a6d6a

Branch: refs/heads/master
Commit: 197a6d6a089271c2568b879a3af5b62440d9d9d6
Parents: 327b89e
Author: Jordan Zimmerman <jo...@jordanzimmerman.com>
Authored: Sat Mar 9 20:26:08 2013 -0800
Committer: Jordan Zimmerman <jo...@jordanzimmerman.com>
Committed: Sat Mar 9 20:26:08 2013 -0800

----------------------------------------------------------------------
 .../src/site/confluence/index.confluence           |   90 +++++++++
 .../src/site/resources/css/site.css                |    4 +
 curator-x-discovery-server/src/site/site.xml       |   27 +++
 .../src/site/confluence/index.confluence           |  155 +++++++++++++++
 .../src/site/resources/css/site.css                |    4 +
 curator-x-discovery/src/site/site.xml              |   27 +++
 src/site/confluence/exhibitor.confluence           |   24 +++
 src/site/confluence/index.confluence               |    4 +-
 src/site/confluence/logging.confluence             |   14 ++
 src/site/confluence/tech-note-1.confluence         |   39 ++++
 src/site/confluence/tech-note-2.confluence         |   19 ++
 src/site/confluence/tech-note-3.confluence         |   25 +++
 src/site/confluence/tech-note-4.confluence         |   17 ++
 src/site/confluence/tech-notes.confluence          |    8 +
 src/site/site.xml                                  |   11 +-
 15 files changed, 464 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/curator-x-discovery-server/src/site/confluence/index.confluence
----------------------------------------------------------------------
diff --git a/curator-x-discovery-server/src/site/confluence/index.confluence b/curator-x-discovery-server/src/site/confluence/index.confluence
new file mode 100644
index 0000000..91d2c18
--- /dev/null
+++ b/curator-x-discovery-server/src/site/confluence/index.confluence
@@ -0,0 +1,90 @@
+h1. Service Discovery Server
+
+h2. Packaging
+Curator Service Discovery is in its own package in Maven Central: {{curator-x-discovery-server}}
+
+h2. Description
+The Service Discovery Server bridges non-Java or legacy applications with the Curator [[Service Discovery|../curator-x-discovery/index.html]].
+It exposes RESTful web services to register, remove, query, etc. services.
+
+The Service Discovery Server provides JAX-RS components that can be incorporated into a container of your choice
+(Tomcat, Jetty, etc.). You can also choose any JAX-RS provider (Jersey, RESTEasy, etc.).
+
+h2. Deploying the Server
+The server must be combined with a JAX-RS implementation (Jersey, etc.) and a container (Tomcat, Jetty, etc.).
+
+Several singletons need to be injected:
+
+* ServiceDiscovery
+* DiscoveryContext
+* JsonServiceInstanceMarshaller
+* JsonServiceInstancesMarshaller
+* JsonServiceNamesMarshaller
+
+Additionally the JAX-RS Resource class must be injected. Due to how most JAX-RS implementations are written, you must
+create a concrete class that extends this using your payload type. The concrete class should have the base path that you'd like to use.
+Because the JAX-RS implementation can create a new instance of the resource for every request, your concrete class must
+use a context resolver to access the DiscoveryContext. Or, if you are using an IoC framework, you can access it that way.
+
+Here's a version that has no payload (i.e. a Void payload):
+{code}
+   @Path("/")
+   public class MyResource extends DiscoveryResource&lt;Void> {
+       public MyResource(@Context ContextResolver&lt;DiscoveryContext&lt;Void>> resolver) {
+           // note: this may not work with all JAX-RS implementations
+           super(resolver.getContext(DiscoveryContext.class));
+       }
+   }
+{code}
+
+h2. REST
+Clients must make appropriate REST calls to register themselves and send periodic heartbeats. They can also find services via REST calls:
+
+h2. putService
+*Method:* PUT
+*Path:* v1/service/{name}/{id}
+*Request Entity:* ServiceInstance
+*Response Entity:* n/a
+*Description:* {name} is the service name, {id} is the instance id. The request entity is a _ServiceInstance_. This
+method registers a service instance. If the ServiceType is STATIC, the instance is registered only for the pre-defined period
+(defined in the DiscoveryContext). STATIC services must call putService at least once per period. PERMANENT services are registered
+until they are manually deleted.
+
+h2. removeService
+*Method:* DELETE
+*Path:* v1/service/{name}/{id}
+*Request Entity:* n/a
+*Response Entity:* n/a
+*Description:* {name} is the service name, {id} is the instance id. The specified service is deleted/unregistered.
+
+h2. get
+*Method:* GET
+*Path:* v1/service/{name}/{id}
+*Request Entity:* n/a
+*Response Entity:* ServiceInstance
+*Description:* {name} is the service name, {id} is the instance id. Returns the complete _ServiceInstance_ for the specified
+service. 404 is returned if not found.
+
+h2. getAllNames
+*Method:* GET
+*Path:* v1/service
+*Request Entity:* n/a
+*Response Entity:* ServiceNames
+*Description:* Returns all currently registered service names.
+
+h2. getAll
+*Method:* GET
+*Path:* v1/service/{name}
+*Request Entity:* n/a
+*Response Entity:* ServiceInstances
+*Description:* {name} is the service name. Returns all service instances for the named service.
+
+h2. getAny
+*Method:* GET
+*Path:* v1/anyservice/{name}
+*Request Entity:* n/a
+*Response Entity:* ServiceInstance
+*Description:* {name} is the service name. Return a random instance from the given service or 404.
+
+h2. JSON specs
+The JSON specifications for the REST entities are documented here: https://github.com/Netflix/curator/tree/master/curator-x-discovery-server

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/curator-x-discovery-server/src/site/resources/css/site.css
----------------------------------------------------------------------
diff --git a/curator-x-discovery-server/src/site/resources/css/site.css b/curator-x-discovery-server/src/site/resources/css/site.css
new file mode 100644
index 0000000..f847d66
--- /dev/null
+++ b/curator-x-discovery-server/src/site/resources/css/site.css
@@ -0,0 +1,4 @@
+tt
+{
+    background-color: transparent;
+}

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/curator-x-discovery-server/src/site/site.xml
----------------------------------------------------------------------
diff --git a/curator-x-discovery-server/src/site/site.xml b/curator-x-discovery-server/src/site/site.xml
new file mode 100644
index 0000000..28a4cbf
--- /dev/null
+++ b/curator-x-discovery-server/src/site/site.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd" name="Discovery Service Server">
+    <body>
+        <breadcrumbs>
+            <item name="Home" href="../index.html"/>
+            <item name="Service Discovery Server" href="index.html"/>
+        </breadcrumbs>
+    </body>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/curator-x-discovery/src/site/confluence/index.confluence
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/site/confluence/index.confluence b/curator-x-discovery/src/site/confluence/index.confluence
new file mode 100644
index 0000000..d87ad4a
--- /dev/null
+++ b/curator-x-discovery/src/site/confluence/index.confluence
@@ -0,0 +1,155 @@
+h1. Service Discovery
+
+h2. Packaging
+
+Curator Service Discovery is in its own package in Maven Central: {{curator-x-discovery}}
+
+h2. What Is a Discovery Service?
+
+In SOA/distributed systems, services need to find each other. i.e. a web service might need to find a caching
+service, etc. DNS can be used for this but it is nowhere near flexible enough for services that are constantly changing.
+A Service Discovery system provides a mechanism for:
+
+* Services to register their availability
+* Locating a single instance of a particular service
+* Notifying when the instances of a service change
+
+h2. Curator Service Discovery
+
+h3. ServiceInstance
+
+A service instance is represented by the class: {{ServiceInstance}}. ServiceInstances have a name, id, address,
+port and/or ssl port, and an optional payload (user defined). ServiceInstances are serialized and stored in ZooKeeper in the following way:
+
+{noformat}
+base path
+       |_______ service A name
+                    |__________ instance 1 id --> (serialized ServiceInstance)
+                    |__________ instance 2 id --> (serialized ServiceInstance)
+                    |__________ ...
+       |_______ service B name
+                    |__________ instance 1 id --> (serialized ServiceInstance)
+                    |__________ instance 2 id --> (serialized ServiceInstance)
+                    |__________ ...
+       |_______ ...
+{noformat}
+
+h3. ServiceProvider
+
+The main abstraction class is {{ServiceProvider}}. It encapsulates the discovery service for a particular
+named service along with a provider strategy. A provider strategy is a scheme for selecting one instance from a set of
+instances for a given service. There are three bundled strategies: Round Robin, Random and Sticky (always selects the same one).
+
+ServiceProviders are allocated by using a {{ServiceProviderBuilder}}. You obtain a ServiceProviderBuilder from the
+ServiceDiscovery (see below). The ServiceProviderBuilder allows you to set the service name and several other optional values.
+
+The ServiceProvider must be started by calling {{start()}}. When finished you should call {{close()}}.
+The only method in ServiceProvider is:
+
+{code}
+public ServiceInstance<T> getInstance()
+                            throws Exception
+Return an instance for a single use. IMPORTANT: users should not hold on to the instance
+returned. A fresh instance should always be retrieved.
+Returns:
+the instance to use
+{code}
+
+h3. ServiceDiscovery
+
+In order to allocate a ServiceProvider, you must have a ServiceDiscovery. It is created by a {{ServiceDiscoveryBuilder}}.
+
+You must call {{start()}} on the object and, when done with it, call {{close()}}.
+
+----
+
+h3. Low Level APIs
+
+The ServiceProvider API is all you should need for most purposes. However, for finer grained control, you can use these methods:
+
+*Registering/Unregistering Services*
+
+Normally, you pass your application's service descriptor to the ServiceDiscovery constructor and it will get registered/unregistered
+automatically. If, though, you need to manually do this, use these methods:
+
+```java
+public void registerService(ServiceInstance<T> service)
+                    throws Exception
+Register/re-register/update a service instance
+Parameters:
+service - service to add
+```
+
+```java
+public void unregisterService(ServiceInstance<T> service)
+                      throws Exception
+Unregister/remove a service instance
+Parameters:
+service - the service
+```
+
+*Querying for Services*
+
+You can query for all service names, all instances of a particular service, or single service instance.
+
+```java
+public Collection<String> queryForNames()
+                              throws Exception
+Return the names of all known services
+Returns:
+list of service names
+```
+
+```java
+public Collection<ServiceInstance<T>> queryForInstances(String name)
+                                            throws Exception
+Return all known instances for the given service
+Parameters:
+name - name of the service
+Returns:
+list of instances (or an empty list)
+```
+
+```java
+public ServiceInstance<T> queryForInstance(String name,
+                                         String id)
+                                 throws Exception
+Return a service instance POJO
+Parameters:
+name - name of the service
+id - ID of the instance
+Returns:
+the instance or null if not found
+```
+
+*Service Cache*
+
+Each of the above query methods calls ZooKeeper directly. If you need more than occasional querying of services you can use the
+{{ServiceCache}}. It caches in memory the list of instances for a particular service. It uses a Watcher to keep the list up to date.
+
+You allocate a ServiceCache via the builder returned by {{ServiceDiscovery.serviceCacheBuilder()}}. The ServiceCache
+object must be started by calling {{start()}} and, when done, you should call {{close()}}. You can get the
+currently known list of instances for the service by calling:
+
+{code}
+public Collection<ServiceInstance<T>> getInstances()
+Return the current list of instances. NOTE: there is no guarantee of freshness. This is merely
+the last known list of instances. However, the list is updated via a ZooKeeper watcher so it
+should be fresh within a window of a second or two.
+{code}
+
+ServiceCache supports a listener that gets notified when Watcher has updated the list of instances:
+
+{code}
+/**
+ * Listener for changes to a service cache
+ */
+public interface ServiceCacheListener extends ConnectionStateListener
+{
+    /**
+     * Called when the cache has changed (instances added/deleted, etc.)
+     */
+    public void cacheChanged();
+}
+{code}
+

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/curator-x-discovery/src/site/resources/css/site.css
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/site/resources/css/site.css b/curator-x-discovery/src/site/resources/css/site.css
new file mode 100644
index 0000000..f847d66
--- /dev/null
+++ b/curator-x-discovery/src/site/resources/css/site.css
@@ -0,0 +1,4 @@
+tt
+{
+    background-color: transparent;
+}

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/curator-x-discovery/src/site/site.xml
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/site/site.xml b/curator-x-discovery/src/site/site.xml
new file mode 100644
index 0000000..0ac7c0e
--- /dev/null
+++ b/curator-x-discovery/src/site/site.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd" name="Discovery Service">
+    <body>
+        <breadcrumbs>
+            <item name="Home" href="../index.html"/>
+            <item name="Service Discovery" href="index.html"/>
+        </breadcrumbs>
+    </body>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/exhibitor.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/exhibitor.confluence b/src/site/confluence/exhibitor.confluence
new file mode 100644
index 0000000..7df24fa
--- /dev/null
+++ b/src/site/confluence/exhibitor.confluence
@@ -0,0 +1,24 @@
+h1. Exhibitor Integration
+
+Curator can be integrated with Netflix [[Exhibitor|https://github.com/Netflix/exhibitor]] to achieve a live/updating list
+of the ZooKeeper ensemble. This means that your ZooKeeper client (i.e. Curator) will automatically/dynamically adjust
+to changes in the makeup of a ZooKeeper ensemble. Further, this support is generalized so that a service other than Exhibitor could be used if available.
+
+h2. Enabling
+
+The integration is enabled via the {{CuratorFrameworkFactory}} (or when constructing the {{CuratorZookeeperClient}} if not
+using the framework). Pass an {{EnsembleProvider}} to the {{ensembleProvider()}} method of the {{CuratorFrameworkFactory}} builder.
+
+h2. EnsembleProvider
+
+For Exhibitor, construct an instance of {{ExhibitorEnsembleProvider}} to pass to the builder. It takes a number of arguments:
+* exhibitors - a list of the exhibitor instances. This is the initial set of Exhibitor instances. This set will get automatically updated if it changes.
+* restClient - a simple facade to access the Exhibitor instances via REST. Use the provided {{DefaultExhibitorRestClient}} or something else of your choosing.
+* restUriPath - the REST path to use. In most cases this should be: {{/exhibitor/v1/cluster/list}}
+* pollingMs - how often to poll the Exhibitor instances
+* retryPolicy - the retry policy to use when polling the Exhibitor instances.
+
+h2. Details
+
+Once configured, Curator will poll the Exhibitors for changes in the ensemble. If Curator should need to re-create the ZooKeeper
+instance (due to a SysDisconnected event, etc.) it will use the updated ensemble list to do so.

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/index.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/index.confluence b/src/site/confluence/index.confluence
index db89fd0..aa21d1e 100644
--- a/src/site/confluence/index.confluence
+++ b/src/site/confluence/index.confluence
@@ -16,8 +16,8 @@ h2. Components
 |[[Recipes|curator-recipes/index.html]]|Implementations of some of the common ZooKeeper "recipes". The implementations are built on top of the Curator Framework.|
 |[[Utilities|utilities.html]]|Various utilities that are useful when using ZooKeeper.|
 |[[Client|curator-client/index.html]]|A replacement for the bundled {{ZooKeeper}} class that takes care of some low-level housekeeping and provides some useful utilities.|
-|[[Errors]]|How Curator deals with errors, connection issues, recoverable exceptions, etc.|
-|[[Extensions]]|Optional/extension recipes for vertical uses.|
+|[[Errors|errors.html]]|How Curator deals with errors, connection issues, recoverable exceptions, etc.|
+|Extensions|The curator-recipes package implements the common recipes that are described in the ZooKeeper documentation. To avoid bloating that package, recipes/applications that have a vertical appeal will be put in separate "extension" packages using the naming convention curator-x-name.|
 
 h2. Maven / Artifacts
 

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/logging.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/logging.confluence b/src/site/confluence/logging.confluence
new file mode 100644
index 0000000..002c655
--- /dev/null
+++ b/src/site/confluence/logging.confluence
@@ -0,0 +1,14 @@
+h1. Logging and Tracing
+
+h2. Details
+Curator is logging and tracing neutral. The Curator code is instrumented with logging and tracers
+but uses a driver mechanism that allows easy integration into your preferred logging and tracing frameworks.
+
+h2. Logging
+Curator uses SLF4J ([[http://www.slf4j.org/]]) for logging. SLF4J is a facade over logging that allows you to
+plug in any (or no) logging framework. See the SLF4J website for details.
+
+h2. Tracing
+Connect Curator tracing to your tracing framework via an instance of {{TracerDriver}}.
+Curator calls the various methods (e.g. addTrace() or addCount() ) and your instance proxies the calls to your tracing
+framework. Inform Curator of your tracing driver instance by calling {{CuratorZookeeperClient.setTracerDriver()}}.

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/tech-note-1.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/tech-note-1.confluence b/src/site/confluence/tech-note-1.confluence
new file mode 100644
index 0000000..663c070
--- /dev/null
+++ b/src/site/confluence/tech-note-1.confluence
@@ -0,0 +1,39 @@
+h1. Tech Note 1
+
+ZooKeeper watches are single threaded.
+
+h2. Details
+
+When your watcher is called, it should return as quickly as possible. All ZooKeeper watchers are serialized -
+processed by a single thread. Thus, *no other watchers can be processed while your watcher is running*. For example, a
+Curator user had a watcher handler something like this:
+
+{code}
+...
+InterProcessMutex   lock = ...
+
+public void process(WatchedEvent event)
+{
+    lock.acquire();
+       ...
+}
+{code}
+
+This *cannot work*. Curator's InterProcessMutex relies on ZooKeeper watchers getting notified. The code above, however,
+is holding on to the ZooKeeper watcher processing thread. The way to fix this is to run the code that needs a lock in a separate thread. e.g.
+
+{code}
+...
+InterProcessMutex   lock = ...
+ExecutorService    service = ...
+
+public void process(WatchedEvent event)
+{
+    service.submit(new Callable<Void>(){
+        Void call() {
+            lock.acquire();
+              ...
+        }
+    });
+}
+{code}

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/tech-note-2.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/tech-note-2.confluence b/src/site/confluence/tech-note-2.confluence
new file mode 100644
index 0000000..78e1414
--- /dev/null
+++ b/src/site/confluence/tech-note-2.confluence
@@ -0,0 +1,19 @@
+h1. Tech Note 2
+
+InterProcessMutex acquire() can be used to return immediately if lock can't be acquired.
+
+h2. Details
+
+It's not obvious from the docs, but calling InterProcessMutex.acquire(0, unit) will return immediately (i.e. without any
+waiting) if the lock cannot be acquired.
+
+e.g.
+
+{code}
+InterProcessMutex lock = ...
+boolean didLock = lock.acquire(0, TimeUnit.any);
+if ( !didLock )
+{
+    // comes back immediately
+}
+{code}

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/tech-note-3.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/tech-note-3.confluence b/src/site/confluence/tech-note-3.confluence
new file mode 100644
index 0000000..8326256
--- /dev/null
+++ b/src/site/confluence/tech-note-3.confluence
@@ -0,0 +1,25 @@
+h1. Tech Note 3
+
+Dealing with session failure.
+
+h2. Details
+
+ZooKeeper clients maintain a session with the server ensemble. Ephemeral nodes are tied to this session.
+When writing ZooKeeper-based applications you must deal with session expirations (due to network partitions,
+server crashes, etc.). This ZooKeeper FAQ discusses it:
+[[http://wiki.apache.org/hadoop/ZooKeeper/FAQ#A3]]
+
+For the most part, Curator shields you from the details of session management. However, Curator's
+behavior can be modified. By default, Curator treats session failures the same way that it treats connection
+failures: i.e. the current retry policy is checked and, if permitted, operations are retried.
+
+There are use-cases, though, where a series of operations must be tied to the ZooKeeper session. For example,
+an ephemeral node is created as a kind of marker then several other ZooKeeper operations are performed. If
+the session were to fail at any point, the entire operation should fail. Curator's default behavior doesn't do this.
+When you need this behavior, use:
+
+{code}
+SessionFailRetryLoop
+{code}
+
+This is similar to the standard retry loop but if a session fails, any future Curator methods (in the same thread) will also fail.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/tech-note-4.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/tech-note-4.confluence b/src/site/confluence/tech-note-4.confluence
new file mode 100644
index 0000000..c61bc0a
--- /dev/null
+++ b/src/site/confluence/tech-note-4.confluence
@@ -0,0 +1,17 @@
+h1. Tech Note 4
+
+ZooKeeper makes a very bad Queue source.
+
+The ZooKeeper recipes page lists Queues as a possible use-case for ZooKeeper. Curator includes
+several Queue recipes. In our experience, however, it is a bad idea to use ZooKeeper as a Queue:
+
+* ZooKeeper has a 1MB transport limitation. In practice this means that ZNodes must be relatively small.
+Typically, queues can contain many thousands of messages.
+
+* ZooKeeper can slow down considerably on startup if there are many large ZNodes. This will be common if
+you are using ZooKeeper for queues. You will need to significantly increase initLimit and syncLimit.
+
+* If a ZNode gets too big it can be extremely difficult to clean. getChildren() will fail on the node. At
+Netflix we had to create a special-purpose program that had a huge value for {{jute.maxbuffer}} in order to get the nodes and delete them.
+
+* ZooKeeper can start to perform badly if there are many nodes with thousands of children.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/confluence/tech-notes.confluence
----------------------------------------------------------------------
diff --git a/src/site/confluence/tech-notes.confluence b/src/site/confluence/tech-notes.confluence
new file mode 100644
index 0000000..c4d8928
--- /dev/null
+++ b/src/site/confluence/tech-notes.confluence
@@ -0,0 +1,8 @@
+h1. Tech Notes
+
+Various questions, issues, etc. come up from time to time. Answers and workarounds will be collected here as Tech Notes.
+
+|[[TN1|tech-note-1.html]]|[[ZooKeeper watches are single threaded|tech-note-1.html]]|
+|[[TN2|tech-note-2.html]]|[[How do I try to lock with InterProcessMutex but return immediately if lock can't be acquired?|tech-note-2.html]]|
+|[[TN3|tech-note-3.html]]|[[Dealing with session failure|tech-note-3.html]]|
+|[[TN4|tech-note-4.html]]|[[ZooKeeper is not a good system to use as a distributed queue|tech-note-4.html]]|

http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/197a6d6a/src/site/site.xml
----------------------------------------------------------------------
diff --git a/src/site/site.xml b/src/site/site.xml
index 4be9b12..edd6d96 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -56,11 +56,18 @@
 
         <menu name="Details" inherit="top">
             <item name="Error Handling" href="errors.html"/>
+            <item name="Logging and Tracing" href="logging.html"/>
+            <item name="Tech Notes" href="tech-notes.html"/>
+            <item name="Exhibitor Integration" href="exhibitor.html"/>
+            <item name="Project Information" href="project-info.html"/>
         </menu>
 
-        <menu ref="reports" />
+        <menu name="Extensions" inherit="top">
+            <item name="Service Discovery" href="curator-x-discovery/index.html"/>
+            <item name="Service Discovery Server" href="curator-x-discovery-server/index.html"/>
+        </menu>
 
-        <menu name="ASF">
+        <menu name="ASF" inherit="bottom">
             <item name="How the ASF works" href="http://www.apache.org/foundation/how-it-works.html"/>
             <item name="Get Involved" href="http://www.apache.org/foundation/getinvolved.html"/>
             <item name="Developer Resources" href="http://www.apache.org/dev/"/>