Reputation: 986
I am observing a strange issue in my program where i am using a single standalone zookeeper and trying to emulate a session expired event for a client. Now as far as i have read the docs and scoured the internet i believe the chain of events proceed as follows. The client connects to the server and receives a negotiated timeout and the server expires the session if no heartbeat is received from the client during the timeout period and even when the client reconnects it will throw a session expired exception.Now to emulate this i have written a following piece of code but somehow it works perfectly fine and no session expired exception is thrown.
String path = "/SessionId3";
ZooKeeper zoo;
final CountDownLatch connectedSignal = new CountDownLatch(1);
zoo = new ZooKeeper("localhost:2182", 5000, new Watcher() {
public void process(WatchedEvent we) {
if (we.getState() == KeeperState.SyncConnected) {
System.out.println("in connected state");
connectedSignal.countDown();
}
if (we.getState() == KeeperState.Disconnected) {
System.out.println("in disconnected state");
connectedSignal.countDown();
}
if (we.getState() == KeeperState.Expired) {
System.out.println("in expired state");
connectedSignal.countDown();
}
if (we.getType() == Event.EventType.None) {
connectedSignal.countDown();
}
}
});
System.out.println("in watcher");
connectedSignal.await();
long sId = zoo.getSessionId();
System.out.println("sessionId=" + sId);
byte[] sPwd = zoo.getSessionPasswd();
System.out.println("session password=" + Arrays.toString(sPwd));
long sTimeout=zoo.getSessionTimeout();
System.out.println("agreed upon session timeout=" +sTimeout);
zoo.create(path,null,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
byte[] data=zoo.getData(path, new Watcher()
{
public void process(WatchedEvent we)
{
if(we.getType()==Event.EventType.NodeDeleted)
{
System.out.println("node deleted");
}
}
}, null);
System.out.println("disconnect from zookeeper servers.");
//here i kill my zookeeper server to make client disconnect
Thread.sleep(30000);
System.out.println("session must have expired...");
Thread.sleep(10000);
System.out.println("after sleep awakening");
//starting zookeeper server again to emulate reconnect
Thread.sleep(10000);
Stat stat = zoo.exists(path, false); //expected to get session expired exception but works fine?
if (stat != null)
{System.out.println("fetching children");
List<String> children=zoo.getChildren(path, false);
for(String child:children)
{
System.out.println(child);
byte[] b = zoo.getData(path+"/"+child, false, null);
String dataInString = new String(b, "UTF-8");
System.out.println(dataInString);
}
} else
{
System.out.println("Node does not exists");
}
zoo.close();//triggers the watch set on ephemeral node
}
also i have a standard zoo.cfg file that comes with zookeeper. What i am doing wrong and why my session is never expired?
Upvotes: 0
Views: 1923
Reputation: 986
Well i found out the issue (i guess). The issue seems to be that when i turn off the zookeeper servers in turn to emulate a session expiry and the client keeps on reconnecting but the point i missed is that the zookeeper server manages session expiry and when i turn it off and turn it on again after some time it resumes the time of session for the client that is trying to connect from the time it was turned off and thats why the session never seem to expire. For proof i tried the client code from another machine and then turnd off its connectivity while keeping the zookeeper server up all the time and after some time reconnected the client again and boom received the session expired notification in the default watcher and got the sessionexpired exception..
Upvotes: 2