ClientWatchManager接口
//接口的唯一方法materialize用于确定那些Watcher需要被通知 //确定Watcher需要三方面的因素1.事件状态 2.事件类型 3.znode的path public interface ClientWatchManager { /** * Return a set of watchers that should be notified of the event. The * manager must not notify the watcher(s), however it will update it's * internal structure as if the watches had triggered. The intent being * that the callee is now responsible for notifying the watchers of the * event, possibly at some later time. * * @param state event state * @param type event type * @param path event path * @return may be empty set but must not be null */ public Set<Watcher> materialize(Watcher.Event.KeeperState state, Watcher.Event.EventType type, String path); }
ZKWatchManager类
private static class ZKWatchManager implements ClientWatchManager { //znode数据更新Watcher private final Map<String, Set<Watcher>> dataWatches = new HashMap<String, Set<Watcher>>(); //znode存在Watcher,即使znode不存在,这个Watcher也可以设置到这个不存在的znode上 private final Map<String, Set<Watcher>> existWatches = new HashMap<String, Set<Watcher>>(); //znode的子znodes个数变化Watcher private final Map<String, Set<Watcher>> childWatches = new HashMap<String, Set<Watcher>>(); //默认的Watcher,如果构造Zookeeper没有显式指定Watcher,则使用这个watcher private volatile Watcher defaultWatcher; //把from中的watcher添加到集合to中 final private void addTo(Set<Watcher> from, Set<Watcher> to) { if (from != null) { to.addAll(from); } } /* (non-Javadoc) * @see org.apache.zookeeper.ClientWatchManager#materialize(Event.KeeperState, * Event.EventType, java.lang.String) */ @Override public Set<Watcher> materialize(Watcher.Event.KeeperState state, Watcher.Event.EventType type, String clientPath) { Set<Watcher> result = new HashSet<Watcher>(); switch (type) { case None://事件类型为None,表示???,把dataWatches,existWatches,childWatches所有的watch都返回 //添加默认的Watcher,只有在类型为None的情况下,才会添加这个默认的Watcher result.add(defaultWatcher); //满足两种情况则清空dataWatches,existWatches,childWatches //1.状态不是SyncConnected(客户端与服务器端已建立链接) //2.设置了System property:zookeepr.disableAutoWatchReset 为true /* zookeeper.disableAutoWatchReset用于控制是否启动Watch自动reset,Clients automatically reset watches during session reconnect */ boolean clear = ClientCnxn.getDisableAutoResetWatch() && state != Watcher.Event.KeeperState.SyncConnected; synchronized(dataWatches) { for(Set<Watcher> ws: dataWatches.values()) { result.addAll(ws); } if (clear) { dataWatches.clear(); } } synchronized(existWatches) { for(Set<Watcher> ws: existWatches.values()) { result.addAll(ws); } if (clear) { existWatches.clear(); } } synchronized(childWatches) { for(Set<Watcher> ws: childWatches.values()) { result.addAll(ws); } if (clear) { childWatches.clear(); } } return result; case NodeDataChanged://如果是单节点发生变化,znode数据变化,znode创建 case NodeCreated: synchronized (dataWatches) { //把clientPath从dataWatches删除掉,加入到result中 addTo(dataWatches.remove(clientPath), result); } synchronized (existWatches) { addTo(existWatches.remove(clientPath), result); } break; case NodeChildrenChanged://子节点发生数目改变 synchronized (childWatches) { addTo(childWatches.remove(clientPath), result); } break; case NodeDeleted://删除节点 synchronized (dataWatches) { addTo(dataWatches.remove(clientPath), result); } // XXX This shouldn't be needed, but just in case synchronized (existWatches) { Set<Watcher> list = existWatches.remove(clientPath); if (list != null) {//list应该 addTo(existWatches.remove(clientPath), result);//只是将clientPath对应的existWatches删除掉,不会加入到result上 LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!"); } } synchronized (childWatches) {//如果一个节点存在子节点,则这个子节点不能被删掉,所以,这地方的逻辑是否会有问题? addTo(childWatches.remove(clientPath), result); } break; default: String msg = "Unhandled watch event type " + type + " with state " + state + " on path " + clientPath; LOG.error(msg); throw new RuntimeException(msg); } return result; } }
默认的Watcher只有事件类型为None的情况下才会设置上,事件类型为Nonde表示什么意思呢?研究了才来更新