zookeeper(9)ソース分析-イベントリスニングWatcher(2)
5007 ワード
次の記事では、Watcherに関連するクラスのソースコードの分析を続けます.
ClientWatchManager
このインタフェースは、実装する方法が1つしかありません.このメソッドは、イベントが発生したときに通知が必要なWatcherの集合を返し、空の集合である可能性があることを示します.
ZKWatchManager
1、ZKWatchManagerはZooKeeperの内部クラスであり、ClientWatchManagerを実現している.2、ZKWatchManagerは3つのMapキー値ペアを定義し、キーはノードパス、値はWatcherである.データが変化するWatcher,ノードが存在するかどうかのWatcher,サブノードが変化するWatcherにそれぞれ対応する.
3、materialize方法
このメソッドは,イベント発生後に通知が必要なWatcher集合を返す.この方法では、まずEventTypeタイプに基づいて対応するイベントタイプを決定し、次にNoneタイプ、すなわちイベントがない場合、clientPath対応するWatcherを3つのキー値ペアから削除し、残りのWatcherセットを結果セットに追加するイベントタイプに応じて対応する操作を行う.NodeDataChangedおよびNodeCreatedイベントの場合、clientPathに対応するWatcherはdataWatchesおよびexistWatchesから削除され、残りのWatcherセットが結果セットに追加されます.
ClientWatchManager
public Set materialize(Watcher.Event.KeeperState state,
Watcher.Event.EventType type, String path);
このインタフェースは、実装する方法が1つしかありません.このメソッドは、イベントが発生したときに通知が必要なWatcherの集合を返し、空の集合である可能性があることを示します.
ZKWatchManager
1、ZKWatchManagerはZooKeeperの内部クラスであり、ClientWatchManagerを実現している.2、ZKWatchManagerは3つのMapキー値ペアを定義し、キーはノードパス、値はWatcherである.データが変化するWatcher,ノードが存在するかどうかのWatcher,サブノードが変化するWatcherにそれぞれ対応する.
static class ZKWatchManager implements ClientWatchManager {
// watchers
private final Map> dataWatches =
new HashMap>();
// watchers
private final Map> existWatches =
new HashMap>();
// watchers
private final Map> childWatches =
new HashMap>();
3、materialize方法
このメソッドは,イベント発生後に通知が必要なWatcher集合を返す.この方法では、まずEventTypeタイプに基づいて対応するイベントタイプを決定し、次にNoneタイプ、すなわちイベントがない場合、clientPath対応するWatcherを3つのキー値ペアから削除し、残りのWatcherセットを結果セットに追加するイベントタイプに応じて対応する操作を行う.NodeDataChangedおよびNodeCreatedイベントの場合、clientPathに対応するWatcherはdataWatchesおよびexistWatchesから削除され、残りのWatcherセットが結果セットに追加されます.
@Override
public Set materialize(Watcher.Event.KeeperState state,
Watcher.Event.EventType type,
String clientPath)
{
//
Set result = new HashSet();
switch (type) {//
case None://
// watcher
result.add(defaultWatcher);
// disableAutoWatchReset Zookeeper
boolean clear = disableAutoWatchReset && state != Watcher.Event.KeeperState.SyncConnected;
// 3 watcherMap
synchronized(dataWatches) {
for(Set ws: dataWatches.values()) {
//
result.addAll(ws);
}
if (clear) { //
dataWatches.clear();
}
}
synchronized(existWatches) {
for(Set ws: existWatches.values()) {
result.addAll(ws);
}
if (clear) {
existWatches.clear();
}
}
synchronized(childWatches) {
for(Set ws: childWatches.values()) {
result.addAll(ws);
}
if (clear) {
childWatches.clear();
}
}
return result;
case NodeDataChanged://
case NodeCreated://
synchronized (dataWatches) {
// clientPath Watcher
addTo(dataWatches.remove(clientPath), result);
}
synchronized (existWatches) {
// clientPath Watcher
addTo(existWatches.remove(clientPath), result);
}
break;
case NodeChildrenChanged: //
synchronized (childWatches) {
// clientPath Watcher
addTo(childWatches.remove(clientPath), result);
}
break;
case NodeDeleted://
synchronized (dataWatches) {
// clientPath Watcher
addTo(dataWatches.remove(clientPath), result);
}
// XXX This shouldn't be needed, but just in case
synchronized (existWatches) {
Set list = existWatches.remove(clientPath);
if (list != null) {
addTo(list, result);
LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");
}
}
synchronized (childWatches) {
// clientPath Watcher
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;
}
}