瀏覽代碼

ZOOKEEPER-593. java client api does not allow client to access negotiated session timeout (phunt via mahadev)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/zookeeper/trunk@903050 13f79535-47bb-0310-9956-ffa450edef68
Mahadev Konar 15 年之前
父節點
當前提交
f0fad0f10e

+ 3 - 0
CHANGES.txt

@@ -257,6 +257,9 @@ IMPROVEMENTS:
   ZOOKEEPER-456. CREATOR_ALL_ACL has unnecessary PERMS.ADMIN in the
   declartion. (phunt via mahadev)
 
+  ZOOKEEPER-593.  java client api does not allow client to access negotiated
+  session timeout (phunt via mahadev)
+
 NEW FEATURES:
   ZOOKEEPER-539. generate eclipse project via ant target. (phunt via mahadev)
 

+ 2 - 1
docs/zookeeperProgrammers.html

@@ -827,7 +827,8 @@ document.write("Last Published: " + document.lastModified);
     responds with the timeout that it can give the client. The current
     implementation requires that the timeout be a minimum of 2 times
     the tickTime (as set in the server configuration) and a maximum of
-    20 times the tickTime.</p>
+    20 times the tickTime. The ZooKeeper client API allows access to
+    the negotiated timeout.</p>
 <p>Another parameter to the ZooKeeper session establishment
     call is the default watcher. Watchers are notified when any state
     change occurs in the client. For example if the client loses

File diff suppressed because it is too large
+ 1 - 1
docs/zookeeperProgrammers.pdf


+ 11 - 0
src/c/include/zookeeper.h

@@ -343,10 +343,21 @@ ZOOAPI int zookeeper_close(zhandle_t *zh);
  */
 ZOOAPI const clientid_t *zoo_client_id(zhandle_t *zh);
 
+/**
+ * \brief return the timeout for this session, only valid if the connections
+ * is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE). This
+ * value may change after a server re-connect.
+ */
 ZOOAPI int zoo_recv_timeout(zhandle_t *zh);
 
+/**
+ * \brief return the context for this handle.
+ */
 ZOOAPI const void *zoo_get_context(zhandle_t *zh);
 
+/**
+ * \brief set the context for this handle.
+ */
 ZOOAPI void zoo_set_context(zhandle_t *zh, void *context);
 
 /**

+ 2 - 1
src/docs/src/documentation/content/xdocs/zookeeperProgrammers.xml

@@ -435,7 +435,8 @@
     responds with the timeout that it can give the client. The current
     implementation requires that the timeout be a minimum of 2 times
     the tickTime (as set in the server configuration) and a maximum of
-    20 times the tickTime.</para>
+    20 times the tickTime. The ZooKeeper client API allows access to
+    the negotiated timeout.</para>
 
     <para>Another parameter to the ZooKeeper session establishment
     call is the default watcher. Watchers are notified when any state

+ 16 - 5
src/java/main/org/apache/zookeeper/ClientCnxn.java

@@ -129,6 +129,13 @@ public class ClientCnxn {
 
     private int connectTimeout;
 
+    /** The timeout in ms the client negotiated with the server. This is the 
+     *  "real" timeout, not the timeout request by the client (which may
+     *  have been increased/decreased by the server which applies bounds
+     *  to this value.
+     */
+    private volatile int negotiatedSessionTimeout;
+
     private int readTimeout;
 
     private final int sessionTimeout;
@@ -165,6 +172,10 @@ public class ClientCnxn {
         return sessionPasswd;
     }
 
+    public int getSessionTimeout() {
+        return negotiatedSessionTimeout;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -668,8 +679,8 @@ public class ClientCnxn {
             BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis);
             ConnectResponse conRsp = new ConnectResponse();
             conRsp.deserialize(bbia, "connect");
-            int sessionTimeout = conRsp.getTimeOut();
-            if (sessionTimeout <= 0) {
+            negotiatedSessionTimeout = conRsp.getTimeOut();
+            if (negotiatedSessionTimeout <= 0) {
                 zooKeeper.state = States.CLOSED;
 
                 eventThread.queueEvent(new WatchedEvent(
@@ -679,8 +690,8 @@ public class ClientCnxn {
                         "Unable to reconnect to ZooKeeper service, session 0x"
                         + Long.toHexString(sessionId) + " has expired");
             }
-            readTimeout = sessionTimeout * 2 / 3;
-            connectTimeout = sessionTimeout / serverAddrs.size();
+            readTimeout = negotiatedSessionTimeout * 2 / 3;
+            connectTimeout = negotiatedSessionTimeout / serverAddrs.size();
             sessionId = conRsp.getSessionId();
             sessionPasswd = conRsp.getPasswd();
             zooKeeper.state = States.CONNECTED;
@@ -689,7 +700,7 @@ public class ClientCnxn {
                         .socket().getRemoteSocketAddress()
                     + ", sessionid = 0x"
                     + Long.toHexString(sessionId)
-                    + ", negotiated timeout = " + sessionTimeout);
+                    + ", negotiated timeout = " + negotiatedSessionTimeout);
             eventThread.queueEvent(new WatchedEvent(Watcher.Event.EventType.None,
                     Watcher.Event.KeeperState.SyncConnected, null));
         }

+ 19 - 1
src/java/main/org/apache/zookeeper/ZooKeeper.java

@@ -472,6 +472,19 @@ public class ZooKeeper {
         return cnxn.getSessionPasswd();
     }
 
+    /**
+     * The negotiated session timeout for this ZooKeeper client instance. The
+     * value returned is not valid until the client connects to a server and
+     * may change after a re-connect.
+     *
+     * This method is NOT thread safe
+     *
+     * @return current session timeout
+     */
+    public int getSessionTimeout() {
+        return cnxn.getSessionTimeout();
+    }
+
     /**
      * Add the specified scheme:auth information to this connection.
      *
@@ -1469,7 +1482,12 @@ public class ZooKeeper {
      */
     @Override
     public String toString() {
-        return ("State:" + getState().toString() + " " + cnxn);
+        States state = getState();
+        return ("State:" + state.toString()
+                + (state == States.CONNECTED ?
+                        " Timeout:" + getSessionTimeout() + " " :
+                        " ")
+                + cnxn);
     }
 
     /*

+ 31 - 1
src/java/test/org/apache/zookeeper/test/SessionTest.java

@@ -53,6 +53,8 @@ public class SessionTest extends TestCase implements Watcher {
     private CountDownLatch startSignal;
 
     File tmpDir;
+    
+    private final int TICK_TIME = 3000;
 
     @Override
     protected void setUp() throws Exception {
@@ -63,7 +65,7 @@ public class SessionTest extends TestCase implements Watcher {
         }
 
         ClientBase.setupTestEnv();
-        ZooKeeperServer zs = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        ZooKeeperServer zs = new ZooKeeperServer(tmpDir, tmpDir, TICK_TIME);
 
         final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
         serverFactory = new NIOServerCnxn.Factory(PORT);
@@ -283,6 +285,34 @@ public class SessionTest extends TestCase implements Watcher {
         zk.close();
     }
 
+    @Test
+    /**
+     * Verify access to the negotiated session timeout.
+     */
+    public void testSessionTimeoutAccess() throws Exception {
+        // validate typical case - requested == negotiated
+        DisconnectableZooKeeper zk = createClient(TICK_TIME * 4);
+        assertEquals(TICK_TIME * 4, zk.getSessionTimeout());
+        // make sure tostring works in both cases
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+
+        // validate lower limit
+        zk = createClient(TICK_TIME);
+        assertEquals(TICK_TIME * 2, zk.getSessionTimeout());
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+
+        // validate upper limit
+        zk = createClient(TICK_TIME * 30);
+        assertEquals(TICK_TIME * 20, zk.getSessionTimeout());
+        LOG.info(zk.toString());
+        zk.close();
+        LOG.info(zk.toString());
+    }
+
     private class DupWatcher extends CountdownWatcher {
         public LinkedList<WatchedEvent> states = new LinkedList<WatchedEvent>();
         public void process(WatchedEvent event) {

Some files were not shown because too many files changed in this diff