[Zookeeper学习笔记之八]Zookeeper源代码分析之Zookeeper.ZKWatchManager

编程技术  /  houtizong 发布于 3年前   100

ClientWatchManager接口

//接口的唯一方法materialize用于确定那些Watcher需要被通知//确定Watcher需要三方面的因素1.事件状态 2.事件类型 3.znode的pathpublic 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表示什么意思呢?研究了才来更新

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客