1. 程式人生 > >Zookeeper原始碼閱讀分析之watcher機制

Zookeeper原始碼閱讀分析之watcher機制


    客戶端ClientWatchManager,管理由ClientXncn產生的watchers和handle events
在zookeeper的exists、getChildren、getData等這些API中可以註冊watcher物件到ClientWatchManager中,
create、setData、delete等這些引起zookeeper節點變化的API會觸發watcher process的執行。

    服務端WatchManager,服務端的watcher物件管理器;
    註冊watcher時候,會在服務端呼叫FinalRequestProcessor.processRequest,註冊client對應的服務端連線物件ServerCnxn(實現了watcher介面)到DataTree中
這樣在觸發server端的watcher時,其實就是觸發ServerCnxn的process方法,在ServerCnxn的process這個實現裡會向對應的註冊watcher物件的client傳送notify訊息,
而客戶端會呼叫對應path註冊的watcher物件的process方法
服務端註冊watcher物件
FinalRequestProcessor.processRequest
             case OpCode.getData: {
        ...............................
                Stat stat = new Stat();
                byte b[] = zks.getZKDatabase().getData(getDataRequest.getPath(), stat,
                        getDataRequest.getWatch() ? cnxn : null);//cnxn為ServerCnxn
                rsp = new GetDataResponse(b, stat);
     watcher的觸發,WatchManager中的trigerWatch(String path,EvenType type),當server接受到例如createNode/deleteNode/setData等操作時,
將會操作ZKDatabase來操作DataTree中的資料,當然dataTree的資料改動,將會觸發相應patch(節點)上的watch(有可能一個操作會導致多種watch被觸發),
trigerWatch就是在這些時機下被呼叫。此操作中就是從watchManager中將相應path下注冊的watch移除,並依次呼叫watch.process()。
此process()做了一件事情,就是向client傳送一個nofication訊息,此訊息中包含一個WatchEvent物件,此物件封裝了事件的型別/path等,

傳送到EventThread中的waitingEvents佇列中,EventThread後臺執行緒從佇列中拉取訊息執行watcher中的process邏輯。

     在ServerCnxn處理請求時出現異常或者client關閉,將會導致ServerCnxn呼叫close()方法,此方法中有個分支操作就是從DataTree中的兩種watches列表中刪除其關聯的watch。