Watcher机制(二)WatchManager

简介: 本文深入分析ZooKeeper中WatchManager类的源码,重点解析其如何通过watchTable和watch2Paths两个映射管理Watcher与节点路径的关联关系,涵盖addWatch、removeWatcher、triggerWatch等核心方法的同步机制与执行流程,揭示事件监听与触发的底层原理。

一、前言  前面已经分析了Watcher机制中的第一部分,即在org.apache.zookeeper下的相关类,接着来分析org.apache.zookeeper.server下的WatchManager类。二、WatchManager源码分析2.1 类的属性 

说明:WatcherManager类用于管理watchers和相应的触发器。watchTable表示从节点路径到watcher集合的映射,而watch2Paths则表示从watcher到所有节点路径集合的映射。2.2 核心方法分析1. size方法说明:可以看到size方法是同步的,因此在多线程环境下是安全的,其主要作用是获取watchTable的大小,即遍历watchTable的值集合。2. addWatch方法说明:addWatch方法同样是同步的,其大致流程如下  ① 通过传入的path(节点路径)从watchTable获取相应的watcher集合,进入②  ② 判断①中的watcher是否为空,若为空,则进入③,否则,进入④  ③ 新生成watcher集合,并将路径path和此集合添加至watchTable中,进入④【类似缓存操作】  ④ 将传入的watcher添加至watcher集合,即完成了path和watcher添加至watchTable的步骤,进入⑤  ⑤ 通过传入的watcher从watch2Paths中获取相应的path集合,进入⑥   ⑥ 判断path集合是否为空,若为空,则进入⑦,否则,进入⑧  ⑦ 新生成path集合,并将watcher和paths添加至watch2Paths中,进入⑧  ⑧ 将传入的path(节点路径)添加至path集合,即完成了path和watcher添加至watch2Paths的步骤。综上:addWatche方法会将:1.入参所对应的watcher添加到入参path所对应的全部Watcher集合中,如path下已有则添加,没有创建新的并添加进去;2.入参所对应的path添加到入参watcher所对应给的所有路径集合中,如watcher对应路径为空则创建新的集合进行添加,非空将入参path直接添加进去。3. removeWatcher方法  说明:removeWatcher用作从watch2Paths和watchTable中中移除该watcher,其大致步骤如下  ① 从watch2Paths中移除传入的watcher,并且返回该watcher对应的路径集合,进入②  ② 判断返回的路径集合是否为空,若为空,直接返回,否则,进入③  ③ 遍历②中的路径集合,对每个路径,都从watchTable中取出与该路径对应的watcher集合,进入④  ④ 若③中的watcher集合不为空,则从该集合中移除watcher,并判断移除元素后的集合大小是否为0,若为0,进入⑤  ⑤ 从watchTable中移除路径4. triggerWatch方法 说明:该方法主要用于触发watch事件,并对事件进行处理。其大致步骤如下  ① 根据事件类型、连接状态、节点路径创建WatchedEvent,进入②  ② 从watchTable中移除传入的path对应的键值对,并且返回path对应的watcher集合,进入③  ③ 判断watcher集合是否为空,若为空,则之后会返回null,否则,进入④  ④ 遍历②中的watcher集合,对每个watcher,从watch2Paths中取出path集合,进入⑤  ⑤ 判断④中的path集合是否为空,若不为空,则从集合中移除传入的path。进入⑥  ⑥ 再次遍历watcher集合,对每个watcher,若supress不为空并且包含了该watcher,则跳过,否则,进入⑦  ⑦ 调用watcher的process方法进行相应处理,之后返回watcher集合。【这里的process具体怎么执行的呢】5. dumpWatches方法

Java

运行代码复制代码public synchronized void removeWatcher(Watcher watcher) {

   // 从wach2Paths中移除watcher,并返回watcher对应的path集合

   HashSet<String> paths = watch2Paths.remove(watcher);

   if (paths == null) { // 集合为空,直接返回

       return;

   }

   for (String p : paths) { // 遍历路径集合

       // 从watcher表中根据路径取出相应的watcher集合

       HashSet<Watcher> list = watchTable.get(p);

       if (list != null) { // 若集合不为空

           // 从list中移除该watcher

           list.remove(watcher);

           if (list.size() == 0) { // 移除后list为空,则从watch表中移出

               watchTable.remove(p);

           }

       }

   }

}

public synchronized void dumpWatches(PrintWriter pwriter, boolean byPath) {

if (byPath) { // 控制写入watchTable或watch2Paths

for (Entry<String, HashSet<Watcher>> e : watchTable.entrySet()) { // 遍历每个键值对

// 写入键

pwriter.println(e.getKey());

for (Watcher w : e.getValue()) { // 遍历值(HashSet<Watcher>)

pwriter.print("\t0x");

pwriter.print(Long.toHexString(((ServerCnxn)w).getSessionId()));

pwriter.print("\n");

}

}

} else {

for (Entry<Watcher, HashSet<String>> e : watch2Paths.entrySet()) { // 遍历每个键值对

// 写入"0x"

pwriter.print("0x");

pwriter.println(Long.toHexString(((ServerCnxn)e.getKey()).getSessionId()));

for (String path : e.getValue()) { // 遍历值(HashSet<String>)

//

pwriter.print("\t");

pwriter.println(path);

}

}

}

}

  说明:dumpWatches用作将watchTable或watch2Paths写入磁盘。三、总结  WatchManager类用作管理watcher、其对应的路径以及触发器,其方法都是针对两个映射的操作。


相关文章
|
机器学习/深度学习 人工智能 云计算
拥抱不确定性:在技术迭代中保持持续学习的心态
【4月更文挑战第22天】 在快速变化的技术世界中,不确定性已成为唯一确定的事物。本文探讨了在不断演进的技术领域中如何维持一种积极的学习态度,以适应和克服挑战。通过分析技术进步的本质、分享个人经验,并提供应对策略,我们强调了终身学习的重要性,并讨论了如何在不确定性中找到成长的机会。
|
17小时前
|
Java
Watcher机制(三)之ZooKeeper
本文深入分析ZooKeeper类的源码,涵盖其内部类、属性、构造函数及核心方法。重点解析Watcher机制中的注册流程,以及create、delete、exists等同步与异步操作的实现原理,揭示ZooKeeper客户端与服务端交互的核心逻辑。
15 0
|
18小时前
|
存储 关系型数据库 MySQL
微服务原理篇(XXLJOB-幂等-MySQL)
本文介绍了XXL-JOB任务调度的优势、组成结构及热点商品缓存更新任务的实现,涵盖幂等性概念与解决方案,并深入解析了MySQL存储引擎特性、索引失效场景、回表与覆盖索引原理以及SQL调优和分库分表策略。
微服务原理篇(XXLJOB-幂等-MySQL)
|
JavaScript 前端开发 Java
|
4月前
|
存储 边缘计算 物联网
RFID技术是如何让仓库实现无人化管理?
RFID技术通过自动识别、实时数据交互和智能调度,实现仓库无人化管理。结合物联网与自动化设备,RFID可完成无人出入库、盘点、分拣与货位管理,提升效率、降低成本,广泛应用于电商、制造、冷链等领域,是智能仓储的核心支撑技术。
|
搜索推荐 语音技术
SenseVoice模型建议
8月更文挑战第4天
1259 1
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
747 3
|
网络协议 Java 数据安全/隐私保护
tcp 可以建立多个连接吗?
【10月更文挑战第25天】TCP(传输控制协议)是一种面向连接的、可靠的传输层协议,它在网络通信中起着重要的作用。在 TCP 中,可以建立多个连接,这种特性被称为TCP 连接复用。
|
算法 安全 量子技术
【2023 年第十三届 MathorCup 高校数学建模挑战赛】 B 题 城市轨道交通列车时刻表优化问题 42页论文及代码
本文介绍了2023年第十三届MathorCup高校数学建模挑战赛B题的研究成果,提供了城市轨道交通列车时刻表优化问题的详细建模方案、C++代码实现以及42页的完整论文,旨在通过贪心算法、二分搜索法和多目标规划等方法最小化企业运营成本并最大化服务水平。
314 0
【2023 年第十三届 MathorCup 高校数学建模挑战赛】 B 题 城市轨道交通列车时刻表优化问题 42页论文及代码
Qt6.5打包(QT windeployqt不是内部或外部命令、QT错误:缺少libgcc_s_seh-1.dll ,无法正常启动(0xc000007b) 问题解决方法)
Qt6.5打包(QT windeployqt不是内部或外部命令、QT错误:缺少libgcc_s_seh-1.dll ,无法正常启动(0xc000007b) 问题解决方法)
1717 1