package org.zookeeper;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import java.util.Arrays;
/**
* User: keyki
*/
public class DataMonitor implements Watcher, AsyncCallback.StatCallback {
private ZooKeeper zooKeeper;
private String zNode;
private boolean dead;
private DataMonitorListener listener;
private byte prevData[];
public DataMonitor(ZooKeeper zooKeeper, String zNode, Executor executor) {
this.zooKeeper = zooKeeper;
this.zNode = zNode;
this.listener = executor;
zooKeeper.exists(zNode, true, this, null);
}
public boolean isDead() {
return dead;
}
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.intValue());
break;
}
} else {
if (path != null && path.equals(zNode)) {
zooKeeper.exists(zNode, true, this, null);
}
}
}
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
boolean exists;
switch (KeeperException.Code.get(rc)) {
case OK:
exists = true;
break;
case NONODE:
exists = false;
break;
case SESSIONEXPIRED:
case NOAUTH:
dead = true;
listener.closing(rc);
return;
default:
// Retry errors
zooKeeper.exists(zNode, true, this, null);
return;
}
byte b[] = null;
if (exists) {
try {
b = zooKeeper.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 && b != prevData) || (b != null && !Arrays.equals(prevData, b))) {
listener.exists(b);
prevData = b;
}
}
}