zookeeper-ZKWatchManager

来源:互联网 发布:淘宝网如何找货源 编辑:程序博客网 时间:2024/05/21 10:53
private static class ZKWatchManager implements ClientWatchManager {    private final Map<String, Set<Watcher>> dataWatches =        new HashMap<String, Set<Watcher>>();    private final Map<String, Set<Watcher>> existWatches =        new HashMap<String, Set<Watcher>>();    private final Map<String, Set<Watcher>> childWatches =        new HashMap<String, Set<Watcher>>();    /**     * 通过zookeeper对象构造函数或register()传递的watcher就是defaultWatcher    **/    private volatile Watcher defaultWatcher;    final private void addTo(Set<Watcher> from, Set<Watcher> to) {        if (from != null) {            to.addAll(from);        }    }    @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:            result.add(defaultWatcher);            /**             * 下面明确的说明了,在默认配置下,SyncConnected重连后不需要重新注册Watcher            * Expired无法自动重连,需要自己重建zookeeper,也就要重新注册Watcher了            **/            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;        /**         * xxxWatches.remove,以下大家可以看出为什么响应一次后要再次注册了        * 同时可以看到,NodeDataChanged和NodeCreated触发dataWatche和existWatche        * NodeChildrenChanged触发chiledWatche        * NodeDeleted触发dataWatche、chiledWatche、existWatche        * */        case NodeDataChanged:        case NodeCreated:            synchronized (dataWatches) {                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) {                    addTo(existWatches.remove(clientPath), 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;    }}
0 0