zoukankan      html  css  js  c++  java
  • zk如何实现watch

    在客户端发送命令:stat /zhang watch

    在zk server中产生如下图的调用栈:

    //在DataTree类中有
    private final WatchManager dataWatches = new WatchManager();
    
    //在WatchManager类中有
    private final HashMap<String, HashSet<Watcher>> watchTable =
        new HashMap<String, HashSet<Watcher>>();
    
    private final HashMap<Watcher, HashSet<String>> watch2Paths =
        new HashMap<Watcher, HashSet<String>>();

    我们详细分析addWatch代码:

    //path就是客户端命令中的"/zhang",而Watcher就是客户端的连接对象NIOServerCnxn
    //可以理解为客户端就是一个Watcher
    //public abstract class ServerCnxn implements Stats, Watcher
    //public class NIOServerCnxn extends ServerCnxn
    public synchronized void addWatch(String path, Watcher watcher) {
        //多个客户端关注一个path
        HashSet<Watcher> list = watchTable.get(path);
        if (list == null) {
            // don't waste memory if there are few watches on a node
            // rehash when the 4th entry is added, doubling size thereafter
            // seems like a good compromise
            list = new HashSet<Watcher>(4);
            watchTable.put(path, list);
        }
        list.add(watcher);
    
        //一个客户端关注多个path
        HashSet<String> paths = watch2Paths.get(watcher);
        if (paths == null) {
            // cnxns typically have many watches, so use default cap here
            paths = new HashSet<String>();
            watch2Paths.put(watcher, paths);
        }
        paths.add(path);
    }

    在创建、删除、设置节点数据时,会触发watch:

    public Set<Watcher> triggerWatch(String path, EventType type, Set<Watcher> supress) {
        //生成事件
        WatchedEvent e = new WatchedEvent(type,    KeeperState.SyncConnected, path);
        HashSet<Watcher> watchers;
        synchronized (this) {
            //删除关注path的客户端
            watchers = watchTable.remove(path);
            if (watchers == null || watchers.isEmpty()) {
                if (LOG.isTraceEnabled()) {
                    ZooTrace.logTraceMessage(LOG,
                            ZooTrace.EVENT_DELIVERY_TRACE_MASK,
                            "No watchers for " + path);
                }
                return null;
            }
            for (Watcher w : watchers) {
                //删除该客户端关注的path
                HashSet<String> paths = watch2Paths.get(w);
                if (paths != null) {
                    paths.remove(path);
                }
            }
        }
        for (Watcher w : watchers) {
            if (supress != null && supress.contains(w)) {
                continue;
            }
            //每个客户端处理watch事件
            //NIOServerCnxn.process(WatchedEvent event)
            w.process(e);
        }
        return watchers;
    }
  • 相关阅读:
    bzoj1415 NOI2005聪聪和可可
    Tyvj1952 Easy
    poj2096 Collecting Bugs
    COGS 1489玩纸牌
    COGS1487 麻球繁衍
    cf 261B.Maxim and Restaurant
    cf 223B.Two Strings
    cf 609E.Minimum spanning tree for each edge
    cf 187B.AlgoRace
    cf 760B.Frodo and pillows
  • 原文地址:https://www.cnblogs.com/allenwas3/p/8081863.html
Copyright © 2011-2022 走看看