Author: mahadev
Date: Fri Aug 7 00:39:19 2009
New Revision: 801852
URL: http://svn.apache.org/viewvc?rev=801852&view=rev
Log:
ZOOKEEPER-484. Clients get SESSION MOVED exception when switching from follower to a leader.
(mahadev)
Modified:
hadoop/zookeeper/branches/branch-3.2/CHANGES.txt
hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java
hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/LeaderZooKeeperServer.java
hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/QuorumTest.java
hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/SessionTest.java
Modified: hadoop/zookeeper/branches/branch-3.2/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/CHANGES.txt?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/CHANGES.txt (original)
+++ hadoop/zookeeper/branches/branch-3.2/CHANGES.txt Fri Aug 7 00:39:19 2009
@@ -45,6 +45,9 @@
ZOOKEEPER-311. handle small path lengths in zoo_create() (chris barroch via breed)
+ ZOOKEEPER-484. Clients get SESSION MOVED exception when switching from
+ follower to a leader. (mahadev)
+
IMPROVEMENTS:
NEW FEATURES:
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
Fri Aug 7 00:39:19 2009
@@ -70,10 +70,7 @@
private ConnectionBean jmxConnectionBean;
- // This is just an arbitrary object to represent requests issued by
- // (aka owned by) this class
- final private static Object me = new Object();
-
+
static public class Factory extends Thread {
ZooKeeperServer zks;
@@ -544,7 +541,7 @@
return;
} else {
Request si = new Request(this, sessionId, h.getXid(), h.getType(), incomingBuffer,
authInfo);
- si.setOwner(me);
+ si.setOwner(ServerCnxn.me);
zk.submitRequest(si);
}
if (h.getXid() >= 0) {
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
Fri Aug 7 00:39:19 2009
@@ -356,7 +356,7 @@
txn = new CreateSessionTxn(to);
request.request.rewind();
zks.sessionTracker.addSession(request.sessionId, to);
- zks.sessionTracker.setOwner(request.sessionId, request.getOwner());
+ zks.setOwner(request.sessionId, request.getOwner());
break;
case OpCode.closeSession:
txnHeader = new TxnHeader(request.sessionId, request.cxid, zks
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ServerCnxn.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
Fri Aug 7 00:39:19 2009
@@ -55,6 +55,10 @@
final static ByteBuffer imok = ByteBuffer.wrap("imok".getBytes());
+ // This is just an arbitrary object to represent requests issued by
+ // (aka owned by) this class
+ final public static Object me = new Object();
+
public abstract int getSessionTimeout();
public abstract void close();
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
Fri Aug 7 00:39:19 2009
@@ -38,6 +38,7 @@
import org.apache.jute.Record;
import org.apache.log4j.Logger;
import org.apache.zookeeper.Environment;
+import org.apache.zookeeper.KeeperException.SessionExpiredException;
import org.apache.zookeeper.ZooDefs.OpCode;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
@@ -500,6 +501,16 @@
return sessionId;
}
+ /**
+ * set the owner of this session as owner
+ * @param id the session id
+ * @param owner the owner of the session
+ * @throws SessionExpiredException
+ */
+ public void setOwner(long id, Object owner) throws SessionExpiredException {
+ sessionTracker.setOwner(id, owner);
+ }
+
protected void revalidateSession(ServerCnxn cnxn, long sessionId,
int sessionTimeout) throws IOException, InterruptedException {
boolean rc = sessionTracker.touchSession(sessionId, sessionTimeout);
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java
Fri Aug 7 00:39:19 2009
@@ -355,6 +355,9 @@
boolean valid = leader.zk.touch(id, to);
if (valid) {
try {
+ //set the session owner
+ // as the follower that
+ // owns the session
leader.zk.setOwner(id, this);
} catch (SessionExpiredException e) {
LOG.error("Somehow session " + Long.toHexString(id) + " expired
right after being renewed! (impossible)", e);
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/LeaderZooKeeperServer.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/LeaderZooKeeperServer.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/LeaderZooKeeperServer.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/main/org/apache/zookeeper/server/quorum/LeaderZooKeeperServer.java
Fri Aug 7 00:39:19 2009
@@ -154,16 +154,14 @@
return "leader";
}
- public void setOwner(long id, Object owner) throws SessionExpiredException {
- sessionTracker.setOwner(id, owner);
- }
-
@Override
protected void revalidateSession(ServerCnxn cnxn, long sessionId,
int sessionTimeout) throws IOException, InterruptedException {
super.revalidateSession(cnxn, sessionId, sessionTimeout);
try {
- setOwner(sessionId, this);
+ // setowner as the leader itself, unless updated
+ // via the follower handlers
+ setOwner(sessionId, ServerCnxn.me);
} catch (SessionExpiredException e) {
// this is ok, it just means that the session revalidation failed.
}
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/QuorumTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/QuorumTest.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/QuorumTest.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/QuorumTest.java
Fri Aug 7 00:39:19 2009
@@ -17,6 +17,8 @@
*/
package org.apache.zookeeper.test;
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
import java.io.IOException;
import java.util.ArrayList;
@@ -29,6 +31,7 @@
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
import org.junit.Before;
import org.junit.Test;
@@ -96,6 +99,41 @@
ct.testMutipleWatcherObjs();
}
+ /**
+ * Make sure that we can change sessions
+ * from follower to leader.
+ *
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws KeeperException
+ */
+ @Test
+ public void testSessionMoved() throws IOException, InterruptedException, KeeperException
{
+ String hostPorts[] = qb.hostPort.split(",");
+ ZooKeeper zk = new DisconnectableZooKeeper(hostPorts[0], ClientBase.CONNECTION_TIMEOUT,
new Watcher() {
+ public void process(WatchedEvent event) {
+ }});
+ zk.create("/sessionMoveTest", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
+ // we want to loop through the list twice
+ for(int i = 0; i < hostPorts.length*2; i++) {
+ // This should stomp the zk handle
+ ZooKeeper zknew = new DisconnectableZooKeeper(hostPorts[(i+1)%hostPorts.length],
ClientBase.CONNECTION_TIMEOUT,
+ new Watcher() {public void process(WatchedEvent event) {
+ }},
+ zk.getSessionId(),
+ zk.getSessionPasswd());
+ zknew.setData("/", new byte[1], -1);
+ try {
+ zk.setData("/", new byte[1], -1);
+ fail("Should have lost the connection");
+ } catch(KeeperException.SessionMovedException e) {
+ }
+ //zk.close();
+ zk = zknew;
+ }
+ zk.close();
+ }
+
@Test
/**
* Connect to two different servers with two different handles using the same session
and
Modified: hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/SessionTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/SessionTest.java?rev=801852&r1=801851&r2=801852&view=diff
==============================================================================
--- hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/SessionTest.java
(original)
+++ hadoop/zookeeper/branches/branch-3.2/src/java/test/org/apache/zookeeper/test/SessionTest.java
Fri Aug 7 00:39:19 2009
@@ -212,31 +212,6 @@
}
}
- /**
- * Make sure that we cannot have two connections with the same
- * session id.
- *
- * @throws IOException
- * @throws InterruptedException
- * @throws KeeperException
- */
- @Test
- public void testSessionMove() throws IOException, InterruptedException, KeeperException
{
- ZooKeeper zk = createClient();
- zk.getChildren("/", false);
- // This should stomp the zk handle
- ZooKeeper zknew = new DisconnectableZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this,
- zk.getSessionId(),
- zk.getSessionPasswd());
- zknew.getChildren("/", false);
- try {
- zk.getChildren("/", false);
- fail("Should have lost the connection");
- } catch(KeeperException.ConnectionLossException e) {
- }
- zknew.close();
- zk.close();
- }
@Test
/**
* This test makes sure that duplicate state changes are not communicated
|