zookeeper (9) source code analysis - an event listener Watcher (2)

Then the article continues to analyze the source code and related Watcher classes.

ClientWatchManager

public Set<Watcher> materialize(Watcher.Event.KeeperState state,
        Watcher.Event.EventType type, String path);

The interface is only one way, the need to achieve. This method represents an event occurs, return to Watcher collection needs to be notified, possibly empty set.

ZKWatchManager

1, ZKWatchManager ZooKeeper is an internal class that implements ClientWatchManager.
2, ZKWatchManager Map defines three key-value pair, the key for the node path, is Watcher. Data corresponding change Watcher, whether existing nodes changes Watcher, child nodes Watcher.

static class ZKWatchManager implements ClientWatchManager {
        //数据变化的watchers
        private final Map<String, Set<Watcher>> dataWatches =
            new HashMap<String, Set<Watcher>>();
        //节点存在与否的watchers
        private final Map<String, Set<Watcher>> existWatches =
            new HashMap<String, Set<Watcher>>();
        //子节点变化的watchers
        private final Map<String, Set<Watcher>> childWatches =
            new HashMap<String, Set<Watcher>>();

3, materialize method

The method after the incident, returned Watcher collection needs to be notified. In this method, first determine the type of the corresponding event according to EventType type, and then make the appropriate action depending on the type of event, such as the type for None, that is, without any incidents, the first three will be deleted from the key-value pairs in clientPath corresponding Watcher, then the remaining Watcher collection added to the result set; for the purposes of NodeDataChanged and NodeCreated event, which will remove clientPath corresponding Watcher from dataWatches and existWatches, and then the remaining Watcher collection added to the result set.

@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://无类型
                //添加默认watcher
                result.add(defaultWatcher);
                //根据disableAutoWatchReset和Zookeeper的状态是否为同步连接判断是否需要清空
                boolean clear = disableAutoWatchReset && state != Watcher.Event.KeeperState.SyncConnected;
                //针对3个不同的watcherMap进行操作
                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:// 节点数据变化
            case NodeCreated:// 创建节点
                synchronized (dataWatches) {
                    //移除clientPath对应的Watcher后全部添加至结果集合
                    addTo(dataWatches.remove(clientPath), result);
                }
                synchronized (existWatches) {
                    //移除clientPath对应的Watcher后全部添加至结果集合
                    addTo(existWatches.remove(clientPath), result);
                }
                break;
            case NodeChildrenChanged: // 节点子节点变化
                synchronized (childWatches) {
                    // 移除clientPath对应的Watcher后全部添加至结果集合
                    addTo(childWatches.remove(clientPath), result);
                }
                break;
            case NodeDeleted:// 删除节点
                synchronized (dataWatches) {
                    // 移除clientPath对应的Watcher后全部添加至结果集合
                    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(list, result);
                        LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");
                    }
                }
                synchronized (childWatches) {
                    //移除clientPath对应的Watcher后全部添加至结果集合
                    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;
        }
    }

Guess you like

Origin blog.51cto.com/janephp/2455948
Recommended