设为首页 收藏本站
查看: 1009|回复: 0

[经验分享] [Zookeeper学习笔记之八]Zookeeper源代码分析之Zookeeper.ZKWatchManager

[复制链接]

尚未签到

发表于 2017-4-19 10:15:38 | 显示全部楼层 |阅读模式
  ClientWatchManager接口

//接口的唯一方法materialize用于确定那些Watcher需要被通知
//确定Watcher需要三方面的因素1.事件状态 2.事件类型 3.znode的path
public interface ClientWatchManager {
/**
* Return a set of watchers that should be notified of the event. The
* manager must not notify the watcher(s), however it will update it's
* internal structure as if the watches had triggered. The intent being
* that the callee is now responsible for notifying the watchers of the
* event, possibly at some later time.
*
* @param state event state
* @param type event type
* @param path event path
* @return may be empty set but must not be null
*/
public Set<Watcher> materialize(Watcher.Event.KeeperState state,
Watcher.Event.EventType type, String path);
}

  ZKWatchManager类

private static class ZKWatchManager implements ClientWatchManager {
//znode数据更新Watcher     
private final Map<String, Set<Watcher>> dataWatches =
new HashMap<String, Set<Watcher>>();
//znode存在Watcher,即使znode不存在,这个Watcher也可以设置到这个不存在的znode上
private final Map<String, Set<Watcher>> existWatches =
new HashMap<String, Set<Watcher>>();
//znode的子znodes个数变化Watcher
private final Map<String, Set<Watcher>> childWatches =
new HashMap<String, Set<Watcher>>();
//默认的Watcher,如果构造Zookeeper没有显式指定Watcher,则使用这个watcher
private volatile Watcher defaultWatcher;
//把from中的watcher添加到集合to中
final private void addTo(Set<Watcher> from, Set<Watcher> to) {
if (from != null) {
to.addAll(from);
}
}
/* (non-Javadoc)
* @see org.apache.zookeeper.ClientWatchManager#materialize(Event.KeeperState,
*                                                        Event.EventType, java.lang.String)
*/
@Override
public Set<Watcher> materialize(Watcher.Event.KeeperState state,
Watcher.Event.EventType type,
String clientPath)
{
Set<Watcher> result = new HashSet<Watcher>();
switch (type) {
case None://事件类型为None,表示???,把dataWatches,existWatches,childWatches所有的watch都返回
//添加默认的Watcher,只有在类型为None的情况下,才会添加这个默认的Watcher
result.add(defaultWatcher);
//满足两种情况则清空dataWatches,existWatches,childWatches
//1.状态不是SyncConnected(客户端与服务器端已建立链接)
//2.设置了System property:zookeepr.disableAutoWatchReset 为true
/*
zookeeper.disableAutoWatchReset用于控制是否启动Watch自动reset,Clients automatically reset watches during session reconnect
*/                     
boolean clear = ClientCnxn.getDisableAutoResetWatch() &&
state != Watcher.Event.KeeperState.SyncConnected;
synchronized(dataWatches) {
for(Set<Watcher> ws: dataWatches.values()) {
result.addAll(ws);
}
if (clear) {
dataWatches.clear();
}
}
synchronized(existWatches) {
for(Set<Watcher> ws: existWatches.values()) {
result.addAll(ws);
}
if (clear) {
existWatches.clear();
}
}
synchronized(childWatches) {
for(Set<Watcher> ws: childWatches.values()) {
result.addAll(ws);
}
if (clear) {
childWatches.clear();
}
}
return result;
case NodeDataChanged://如果是单节点发生变化,znode数据变化,znode创建
case NodeCreated:
synchronized (dataWatches) {
//把clientPath从dataWatches删除掉,加入到result中
addTo(dataWatches.remove(clientPath), result);
}
synchronized (existWatches) {
addTo(existWatches.remove(clientPath), result);
}
break;
case NodeChildrenChanged://子节点发生数目改变
synchronized (childWatches) {
addTo(childWatches.remove(clientPath), result);
}
break;
case NodeDeleted://删除节点
synchronized (dataWatches) {
addTo(dataWatches.remove(clientPath), result);
}
// XXX This shouldn't be needed, but just in case
synchronized (existWatches) {
Set<Watcher> list = existWatches.remove(clientPath);
if (list != null) {//list应该
addTo(existWatches.remove(clientPath), result);//只是将clientPath对应的existWatches删除掉,不会加入到result上
LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");
}
}
synchronized (childWatches) {//如果一个节点存在子节点,则这个子节点不能被删掉,所以,这地方的逻辑是否会有问题?
addTo(childWatches.remove(clientPath), result);
}
break;
default:
String msg = "Unhandled watch event type " + type
+ " with state " + state + " on path " + clientPath;
LOG.error(msg);
throw new RuntimeException(msg);
}
return result;
}
}
  默认的Watcher只有事件类型为None的情况下才会设置上,事件类型为Nonde表示什么意思呢?研究了才来更新

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-366242-1-1.html 上篇帖子: Paxos算法与Zookeeper分析 下篇帖子: session复制/ memcached / zookeeper
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表