2021SC@SDUSC
WatchManager
我们接着分析WatchManager类的成员函数
removeWatcher方法
public synchronized void removeWatcher(Watcher watcher) {
//从watch2Paths中移除watcher,返回watcher所对应的path集合,存在paths变量中
Set<String> paths = watch2Paths.remove(watcher);
//集合为空,就直接返回
if (paths == null) {
return;
}
//遍历path集合
for (String p : paths) {
//通过watchTable取出一个路径所对应的watcher集合
Set<Watcher> list = watchTable.get(p);
//如果watcher集合不为空
if (list != null) {
//从watcher集合里移除watcher(该函数的参数)
list.remove(watcher);
//如果移除后,wacher集合没有元素了,那么就可以对watchTable移除该路径了
if (list.isEmpty()) {
watchTable.remove(p);
}
}
//维护watcherModeManager
watcherModeManager.removeWatcher(watcher, p);
}
}
public synchronized boolean removeWatcher(String path, Watcher watcher) {
//从watch2Paths中移除watcher,返回watcher所对应的path集合,存在paths变量中
Set<String> paths = watch2Paths.get(watcher);
//集合为空或者集合里不含path(该函数传入的参数),返回false
if (paths == null || !paths.remove(path)) {
return false;
}
//从watchTable查找path对应的wacher集合
Set<Watcher> list = watchTable.get(path);
//如果集合为空或者wacher集合里不含wacher(该函数传入的参数),返回false
if (list == null || !list.remove(watcher)) {
return false;
}
//如果集合元素个数为0,那么维护watchTable,移除path
if (list.isEmpty()) {
watchTable.remove(path);
}
//维护watcherModeManager
watcherModeManager.removeWatcher(watcher, path);
return true;
}
triggerWatch方法
//调用同名方法,第三个参数为null
public WatcherOrBitSet triggerWatch(String path, EventType type) {
return triggerWatch(path, type, null);
}
public WatcherOrBitSet triggerWatch(String path, EventType type, WatcherOrBitSet supress) {
//根据事件类型、连接状态、节点路径创建WatchedEvent
WatchedEvent e = new WatchedEvent(type, KeeperState.SyncConnected, path);
//创建watcher集合
Set<Watcher> watchers = new HashSet<>();
PathParentIterator pathParentIterator = getPathParentIterator(path);
//同步块
synchronized (this) {
for (String localPath : pathParentIterator.asIterable()) {
Set<Watcher> thisWatchers = watchTable.get(localPath);
if (thisWatchers == null || thisWatchers.isEmpty()) {
continue;
}
Iterator<Watcher> iterator = thisWatchers.iterator();
while (iterator.hasNext()) {
Watcher watcher = iterator.next();
WatcherMode watcherMode = watcherModeManager.getWatcherMode(watcher, localPath);
if (watcherMode.isRecursive()) {
if (type != EventType.NodeChildrenChanged) {
watchers.add(watcher);
}
} else if (!pathParentIterator.atParentPath()) {
watchers.add(watcher);
if (!watcherMode.isPersistent()) {
iterator.remove();
Set<String> paths = watch2Paths.get(watcher);
if (paths != null) {
paths.remove(localPath);
}
}
}
}
if (thisWatchers.isEmpty()) {
watchTable.remove(localPath);
}
}
}
if (watchers.isEmpty()) {
if (LOG.isTraceEnabled()) {
ZooTrace.logTraceMessage(LOG, ZooTrace.EVENT_DELIVERY_TRACE_MASK, "No watchers for " + path);
}
return null;
}
//遍历watcher集合
for (Watcher w : watchers) {
//supress不为空且包含watcher,就跳过
if (supress != null && supress.contains(w)) {
continue;
}
//进行扫描
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);
}
dumpWatches方法
//将watchTable或watch2Paths写入磁盘
public synchronized void dumpWatches(PrintWriter pwriter, boolean byPath) {
//控制写入watchTable或watch2Paths
if (byPath) {
//遍历键值对
for (Entry<String, Set<Watcher>> e : watchTable.entrySet()) {
//写入键
pwriter.println(e.getKey());
//遍历值
for (Watcher w : e.getValue()) {
pwriter.print("\t0x");
pwriter.print(Long.toHexString(((ServerCnxn) w).getSessionId()));
pwriter.print("\n");
}
}
} else {
//遍历键值对
for (Entry<Watcher, Set<String>> e : watch2Paths.entrySet()) {
//写入“0x”
pwriter.print("0x");
pwriter.println(Long.toHexString(((ServerCnxn) e.getKey()).getSessionId()));
//遍历值
for (String path : e.getValue()) {
pwriter.print("\t");
pwriter.println(path);
}
}
}
}
containsWatcher方法
//判断给定的路径是否有指定的watcher
public synchronized boolean containsWatcher(String path, Watcher watcher) {
WatcherMode watcherMode = watcherModeManager.getWatcherMode(watcher, path);
PathParentIterator pathParentIterator = getPathParentIterator(path);
for (String localPath : pathParentIterator.asIterable()) {
Set<Watcher> watchers = watchTable.get(localPath);
if (!pathParentIterator.atParentPath()) {
if (watchers != null) {
return true; // at the leaf node, all watcher types match
}
}
if (watcherMode.isRecursive()) {
return true;
}
}
return false;
}
getWatches方法
//返回一个watch报告
public synchronized WatchesReport getWatches() {
Map<Long, Set<String>> id2paths = new HashMap<>();
for (Entry<Watcher, Set<String>> e : watch2Paths.entrySet()) {
Long id = ((ServerCnxn) e.getKey()).getSessionId();
Set<String> paths = new HashSet<>(e.getValue());
id2paths.put(id, paths);
}
return new WatchesReport(id2paths);
}
getWatchesByPath方法
//返回一个watch报告(这个报告本质上是一个映射(从路径映射到在该路径上设置watch的会话的会话ID)
public synchronized WatchesPathReport getWatchesByPath() {
Map<String, Set<Long>> path2ids = new HashMap<>();
for (Entry<String, Set<Watcher>> e : watchTable.entrySet()) {
Set<Long> ids = new HashSet<>(e.getValue().size());
path2ids.put(e.getKey(), ids);
for (Watcher watcher : e.getValue()) {
ids.add(((ServerCnxn) watcher).getSessionId());
}
}
return new WatchesPathReport(path2ids);
}
getWatchesSummary方法
//获取watch信息概要
public synchronized WatchesSummary getWatchesSummary() {
int totalWatches = 0;
for (Set<String> paths : watch2Paths.values()) {
totalWatches += paths.size();
}
return new WatchesSummary(watch2Paths.size(), watchTable.size(), totalWatches);
}
shutdown方法
//空方法,什么都不做
public void shutdown() { }
getRecursiveWatchQty方法
//获取递归watcher的当前数量
public int getRecursiveWatchQty() {
return watcherModeManager.getRecursiveQty();
}
isDeadWatcher方法
//判断watcher是否已经挂了(具体地,这个方法保证了,如果返回true,那么连接一定是关闭或者将关闭的)
private boolean isDeadWatcher(Watcher watcher) {
return watcher instanceof ServerCnxn && ((ServerCnxn) watcher).isStale();
}
getPathParentIterator方法
//获取PathParent迭代器
private PathParentIterator getPathParentIterator(String path) {
if (watcherModeManager.getRecursiveQty() == 0) {
return PathParentIterator.forPathOnly(path);
}
return PathParentIterator.forAll(path);
}
剩下的就是常规的toString方法了