当前位置:首页 > 开发 > 开源软件 > 正文

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

发表于: 2014-07-30   作者:bit1129   来源:转载   浏览:
摘要: ClientWatchManager接口 //接口的唯一方法materialize用于确定那些Watcher需要被通知 //确定Watcher需要三方面的因素1.事件状态 2.事件类型 3.znode的path public interface ClientWatchManager { /** * Return a set of watchers that should

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表示什么意思呢?研究了才来更新

 

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Zookeeper的会话状态变迁图: Connection Loss: CONNECTION_LOSS意味着客户端和服务器端的连接断开
Zookeeper的会话状态变迁图: Connection Loss: CONNECTION_LOSS意味着客户端和服务器端的连接断开
Zookeeper的会话状态变迁图: Connection Loss: CONNECTION_LOSS意味着客户端和服务器端的连接断开
1. 什么是ZooKeeper? ZooKeeper是一组工具,用来配置和支持分布式调度。以我的理解,就是一个网管
   在ubutun上用了一下ZK的java的api.感觉不错,挺好用的.当然首先要启动ZK服务器. 然后需要
Zookeeper 是Hadoop的高可用高性能的分布式协调服务。 1 Partial Failure 部分失败 即:我们不知道
分布式架构是中心化的设计,就是一个主控机连接多个处理节点,因此保证主控机高可用性十分关键.分布
如果你喜欢命令行式交互型的监控,不妨使用这个小工具。 github地址:https://github.com/phunt/zkt
如果我们要写一个ZooKeeper的client程序,那么有一个相关的配置:connect string,它通常以用逗号分
这是淘宝上的开源项目,地址:http://code.taobao.org/p/zkweb/wiki/index/ 这是一个Java写的web应
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号