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 是什么结构,为什么会产生这种结构类型?