zk的watcher模型(下)

孤者浪人 提交于 2019-11-30 13:32:29

 

watcher在zk server中实现

WatcherManager存储管理

属性:

private final Map<String, Set<Watcher>> watchTable = new HashMap<String, Set<Watcher>>();
路径和watcher的对应关系

private final Map<Watcher, Set<String>> watch2Paths = new HashMap<Watcher, Set<String>>();
watcher和路径集合的对应关系 
方法: 
使用synchronized同步方法,不够灵活,线程不能中断,效率不够高
public synchronized int size() {
    int result = 0;
    for (Set<Watcher> watches : watchTable.values()) {
        result += watches.size();
    }
    return result;
}
添加watcher
@Override
public synchronized boolean addWatch(String path, Watcher watcher) {
    if (isDeadWatcher(watcher)) {
        LOG.debug("Ignoring addWatch with closed cnxn");
        return false;
    }

    Set<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);

    Set<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);
    }
    return paths.add(path);
}



删除watcher
@Override
public synchronized void removeWatcher(Watcher watcher) {
    //移除watcher,并将路径取出
    Set<String> paths = watch2Paths.remove(watcher);
    if (paths == null) {
        return;
    }
    for (String p : paths) {
        //通过路径取出watcher
        Set<Watcher> list = watchTable.get(p);
        if (list != null) {
            //set中remove watcher
            list.remove(watcher);
            if (list.isEmpty()) {
                //watcher为空,直接移除路径
                watchTable.remove(p);
            }
        }
    }
}


触发watcher(非禁止supress类型观察者)
@Override
public WatcherOrBitSet triggerWatch(String path, EventType type, WatcherOrBitSet supress) {
    //创建事件
    WatchedEvent e = new WatchedEvent(type, KeeperState.SyncConnected, path);
    Set<Watcher> watchers;
    synchronized (this) {
        //通过path移除watchers
        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) {
            Set<String> paths = watch2Paths.get(w);
            if (paths != null) {
                paths.remove(path);
            }
        }
    }
    for (Watcher w : watchers) {
        if (supress != null && supress.contains(w)) {
            continue;
        }
        //watcher 处理事件e
        w.process(e);
    }

    //事件类型处理
    switch (type) {
        //节点创建
    case NodeCreated:
        ServerMetrics.getMetrics().NODE_CREATED_WATCHER.add(watchers.size());
        break;
    //节点删除
    case NodeDeleted:
        ServerMetrics.getMetrics().NODE_DELETED_WATCHER.add(watchers.size());
        break;
    //节点数据变化
    case NodeDataChanged:
        ServerMetrics.getMetrics().NODE_CHANGED_WATCHER.add(watchers.size());
        break;
    //子节点变化
    case NodeChildrenChanged:
        ServerMetrics.getMetrics().NODE_CHILDREN_WATCHER.add(watchers.size());
        break;
    default:
        // Other types not logged.
        break;
    }

    return new WatcherOrBitSet(watchers);
}

 

思考:

1 w.process(e); 这里是具体做了什么事情

2 WatcherOrBitSet 是什么结构,为什么会产生这种结构类型?

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!