Zookeeper C 異步 API 介紹

在講解 Zookeeper 異步 API ,除了監視器回調函數以外,還有其他 7 種回調函數,他們通常在異步 API 調用結束或 Zookeeper  客戶端失去連接時被調用。根據回調函數返回參數(即函數的輸出參數)的類型不同分爲以下幾類:返回 void 類型的回調函數,返回 Stat 結構的回調函數,返回字符串的回調函數,返回數據的回調函數,返回字符串列表(a list of string)的回調函數,同時返回字符串列表(a list of string)和 Stat 結構的回調函數,以及返回 ACL 信息的回調函數,7 中回調函數原型聲明如下:

複製代碼
// 返回 void 類型的回調函數
typedef void(* void_completion_t)(int rc, const void *data);

// 返回 Stat 結構的回調函數
typedef void(* stat_completion_t)(int rc, const struct Stat *stat, const void *data); 

// 返回字符串的回調函數
typedef void(* string_completion_t)(int rc, const char *value, const void *data); 

// 返回數據的回調函數
typedef void(* data_completion_t)(int rc, const char *value, int value_len, const struct Stat *stat, const void *data); 

// 返回字符串列表(a list of string)的回調函數
typedef void(* strings_completion_t)(int rc, const struct String_vector *strings, const void *data); 

// 同時返回字符串列表(a list of string)和 Stat 結構的回調函數
typedef void(* strings_stat_completion_t)(int rc, const struct String_vector *strings, const struct Stat *stat, const void *data); 

// 以及返回 ACL 信息的回調函數
typedef void(* acl_completion_t)(int rc, struct ACL_vector *acl, struct Stat *stat, const void *data);
複製代碼

 可能這麼說還不是很理解,那麼我們以異步創建 znode 節點(zoo_acreate())爲例解釋一下:

zoo_acreate函數原型如下:

ZOOAPI int zoo_acreate(zhandle_t * zh, const char *path,
                       const char *value, int valuelen,
                       const struct ACL_vector *acl, int flags,
                       string_completion_t completion, const void *data);

其中參數 string_completion_t completion 即返回字符串的回調函數,那麼當 zoo_acreate 調用結束時將會觸發 completion 回調函數的調用,同時傳遞給 completion 的 rc 參數爲: ZOK 操作完成;ZNONODE 父節點不存在;ZNODEEXISTS 節點已存在;ZNOAUTH 客戶端沒有權限創建節點。ZNOCHILDRENFOREPHEMERALS 臨時節點不能創建子節點。而 string_completion_t completion 中 const char *value 參數即新節點的路徑名(注:如果 zoo_acreate 設置了ZOO_EPHEMERAL,則創建節點成功後,節點名稱並不是 zoo_acreate 中 path 參數所指定的名稱,而是類似與 /xyz0000000001,/xyz0000000002... 的名稱)。另外,string_completion_t completion 中 const void *data 參數即爲 zoo_acreate 中的 const void *data。

一般來說,zoo_acreate 函數可以按照以下方式調用:

複製代碼
    int ret = zoo_acreate(zkhandle, "/xyz", "hello", 5,
           &ZOO_OPEN_ACL_UNSAFE, 0 /* ZOO_SEQUENCE */,
           zktest_string_completion, "acreate");
    if (ret) {
        fprintf(stderr, "Error %d for %s\n", ret, "acreate");
        exit(EXIT_FAILURE);
    }
複製代碼

 其中 zktest_string_completion 功能很簡單,就是把創建成功後的節點名稱打印出來,函數定義如下:

複製代碼
void zktest_string_completion(int rc, const char *name, const void *data)
{
    fprintf(stderr, "[%s]: rc = %d\n", (char*)(data==0?"null":data), rc);
    if (!rc) {
        fprintf(stderr, "\tname = %s\n", name);
    }
}
複製代碼

 好了,有了上面的基礎,我們接下來再來講講 Zookeeper 異步 API 吧 :-)

Zookeeper C API 中與訪問 Zookeeper 服務相關(比如創建、刪除 znode 節點,獲取子節點,設置 znode 數據等)的異步 API 如下:

複製代碼
ZOOAPI int zoo_acreate(zhandle_t * zh, const char *path,
                       const char *value, int valuelen,
                       const struct ACL_vector *acl, int flags,
                       string_completion_t completion, const void *data);

ZOOAPI int zoo_adelete(zhandle_t * zh, const char *path, int version,
                       void_completion_t completion, const void *data);

ZOOAPI int zoo_aexists(zhandle_t * zh, const char *path, int watch,
                       stat_completion_t completion, const void *data);

ZOOAPI int zoo_awexists(zhandle_t * zh, const char *path,
                        watcher_fn watcher, void *watcherCtx,
                        stat_completion_t completion, const void *data);

ZOOAPI int zoo_aget(zhandle_t * zh, const char *path, int watch,
                    data_completion_t completion, const void *data);

ZOOAPI int zoo_awget(zhandle_t * zh, const char *path,
                     watcher_fn watcher, void *watcherCtx,
                     data_completion_t completion, const void *data);

ZOOAPI int zoo_aset(zhandle_t * zh, const char *path,
                    const char *buffer, int buflen, int version,
                    stat_completion_t completion, const void *data);

ZOOAPI int zoo_aget_children(zhandle_t * zh, const char *path,
                             int watch,
                             strings_completion_t completion,
                             const void *data);

ZOOAPI int zoo_awget_children(zhandle_t * zh, const char *path,
                              watcher_fn watcher, void *watcherCtx,
                              strings_completion_t completion,
                              const void *data);

ZOOAPI int zoo_aget_children2(zhandle_t * zh, const char *path,
                              int watch,
                              strings_stat_completion_t completion,
                              const void *data);

ZOOAPI int zoo_awget_children2(zhandle_t * zh, const char *path,
                               watcher_fn watcher, void *watcherCtx,
                               strings_stat_completion_t completion,
                               const void *data);

ZOOAPI int zoo_async(zhandle_t * zh, const char *path,
                     string_completion_t completion, const void *data);

ZOOAPI int zoo_aget_acl(zhandle_t * zh, const char *path,
                        acl_completion_t completion, const void *data);

ZOOAPI int zoo_aset_acl(zhandle_t * zh, const char *path, int version,
                        struct ACL_vector *acl, void_completion_t,
                        const void *data);

ZOOAPI int zoo_amulti(zhandle_t * zh, int count, const zoo_op_t * ops,
                      zoo_op_result_t * results, void_completion_t,
                      const void *data);
複製代碼

本文將以上異步 API 細分爲以下幾類:(1). 創建、刪除 znode 節點,(2). 可設置 watch 的 API,(3). 訪問、設置節點 ACL 的 API,(4). 異步批處理 API。

  •  創建、刪除 znode 節點
複製代碼
ZOOAPI int zoo_acreate(zhandle_t * zh, const char *path,
                       const char *value, int valuelen,
                       const struct ACL_vector *acl, int flags,
                       string_completion_t completion, const void *data);

ZOOAPI int zoo_adelete(zhandle_t * zh, const char *path, int version,
                       void_completion_t completion, const void *data);
複製代碼
  • 創建 znode 節點
ZOOAPI int zoo_acreate(zhandle_t * zh, const char *path,
                       const char *value, int valuelen,
                       const struct ACL_vector *acl, int flags,
                       string_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
value該節點保存的數據。
valuelen該節點保存數據的大小。
acl該節點初始 ACL,ACL 不能爲null 或空。
flags該參數可以設置爲 0,或者創建標識符 ZOO_EPHEMERALZOO_SEQUENCE 的組合或(OR)。
completion當創建節點請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 父節點不存在;ZNODEEXISTS 節點已存在;ZNOAUTH 客戶端沒有權限創建節點。ZNOCHILDRENFOREPHEMERALS 臨時節點不能創建子節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。
  • 刪除 znode 節點
ZOOAPI int zoo_adelete(zhandle_t * zh, const char *path, int version,
                       void_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
version期望的節點版本號,如果真實的版本號與期望的版本號不同則 zoo_delete() 調用失敗,-1 表示不不檢查版本號。
completion當刪除節點請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點;ZBADVERSION 版包號不匹配;ZNOTEMPTY 當前節點存在子節點,不能被刪除。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

  • 可設置 watch 的 API(exists(兩個) + get(兩個) + get_children(四個) = 八個)
複製代碼
ZOOAPI int zoo_aexists(zhandle_t * zh, const char *path, int watch,
                       stat_completion_t completion, const void *data);

ZOOAPI int zoo_awexists(zhandle_t * zh, const char *path,
                        watcher_fn watcher, void *watcherCtx,
                        stat_completion_t completion, const void *data);

ZOOAPI int zoo_aget(zhandle_t * zh, const char *path, int watch,
                    data_completion_t completion, const void *data);

ZOOAPI int zoo_awget(zhandle_t * zh, const char *path,
                     watcher_fn watcher, void *watcherCtx,
                     data_completion_t completion, const void *data);

ZOOAPI int zoo_aget_children(zhandle_t * zh, const char *path,
                             int watch,
                             strings_completion_t completion,
                             const void *data);

ZOOAPI int zoo_awget_children(zhandle_t * zh, const char *path,
                              watcher_fn watcher, void *watcherCtx,
                              strings_completion_t completion,
                              const void *data);

ZOOAPI int zoo_aget_children2(zhandle_t * zh, const char *path,
                              int watch,
                              strings_stat_completion_t completion,
                              const void *data);

ZOOAPI int zoo_awget_children2(zhandle_t * zh, const char *path,
                               watcher_fn watcher, void *watcherCtx,
                               strings_stat_completion_t completion,
                               const void *data);
複製代碼
  • 檢查節點狀態 exists(兩個,分別是 zoo_aexists() 和 zoo_awexists(),區別是後者可以指定單獨的 watcher_fn(監視器回調函數),而前者只能用 zookeeper_init() 設置的全局監視器回調函數,同時 aget 和 aget_children兩族函數也一樣,帶有zoo_w* 的函數可以指定單獨的 watcher_fn)。)
ZOOAPI int zoo_aexists(zhandle_t * zh, const char *path, int watch,
                       stat_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watch如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知,即使當前指定的節點不存在也會設置監視,這樣該節點被創建時,客戶端也可以得到通知。
completion當 zoo_aexists 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

ZOOAPI int zoo_awexists(zhandle_t * zh, const char *path,
                        watcher_fn watcher, void *watcherCtx,
                        stat_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watcher如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知,即使當前指定的節點不存在也會設置監視,這樣該節點被創建時,客戶端也可以得到通知。
watcherCtx用戶指定的數據,將被傳入到監視器回調函數中,與由 zookeeper_init() 設置的全局監視器上下文不同,該函數設置的監視器上下文只與當前的監視器相關聯。
completion當 zoo_awexists 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

  • 獲取節點數據 aget(兩個)
ZOOAPI int zoo_aget(zhandle_t * zh, const char *path, int watch,
                    data_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watch如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知。
completion當 zoo_aget 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

ZOOAPI int zoo_awget(zhandle_t * zh, const char *path,
                     watcher_fn watcher, void *watcherCtx,
                     data_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watcher如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知,即使當前指定的節點不存在也會設置監視,這樣該節點被創建時,客戶端也可以得到通知。
watcherCtx用戶指定的數據,將被傳入到監視器回調函數中,與由 zookeeper_init() 設置的全局監視器上下文不同,該函數設置的監視器上下文只與當前的監視器相關聯。
completion當 zoo_awget 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

  • 獲取子節點列表 aget_children (四個)
ZOOAPI int zoo_aget_children(zhandle_t * zh, const char *path,
                             int watch,
                             strings_completion_t completion,
                             const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watch如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知。
completion當 zoo_aget_children 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

ZOOAPI int zoo_awget_children(zhandle_t * zh, const char *path,
                              watcher_fn watcher, void *watcherCtx,
                              strings_completion_t completion,
                              const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watcher如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知,即使當前指定的節點不存在也會設置監視,這樣該節點被創建時,客戶端也可以得到通知。
watcherCtx用戶指定的數據,將被傳入到監視器回調函數中,與由 zookeeper_init() 設置的全局監視器上下文不同,該函數設置的監視器上下文只與當前的監視器相關聯。
completion當zoo_awget_children 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

ZOOAPI int zoo_aget_children2(zhandle_t * zh, const char *path,
                              int watch,
                              strings_stat_completion_t completion,
                              const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watch如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知。
completion當 zoo_aget_children2 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

ZOOAPI int zoo_awget_children2(zhandle_t * zh, const char *path,
                               watcher_fn watcher, void *watcherCtx,
                               strings_stat_completion_t completion,
                               const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
watcher如果非 0,則在服務器端設置監視,當節點發生變化時客戶端會得到通知,即使當前指定的節點不存在也會設置監視,這樣該節點被創建時,客戶端也可以得到通知。
watcherCtx用戶指定的數據,將被傳入到監視器回調函數中,與由 zookeeper_init() 設置的全局監視器上下文不同,該函數設置的監視器上下文只與當前的監視器相關聯。
completion當zoo_awget_children2 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

  • 訪問、設置節點 ACL 的 API
複製代碼
ZOOAPI int zoo_aget_acl(zhandle_t * zh, const char *path,
                        acl_completion_t completion, const void *data);

ZOOAPI int zoo_aset_acl(zhandle_t * zh, const char *path, int version,
                        struct ACL_vector *acl, void_completion_t,
                        const void *data);
複製代碼
  • 訪問節點 ACL
ZOOAPI int zoo_aget_acl(zhandle_t * zh, const char *path,
                        acl_completion_t completion, const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
completion當 zoo_aget_acl 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

  • 設置節點 ACL
ZOOAPI int zoo_aset_acl(zhandle_t * zh, const char *path, int version,
                        struct ACL_vector *acl, void_completion_t,
                        const void *data);
zhzookeeper_init() 返回的 zookeeper 句柄。
path節點路徑。
buffer保存需要設置的 ACL。
buflenbuffer 的長度。
completion當 zoo_aset_acl 請求完成時會調用該函數,該函數原型詳見第三講《回調函數》一節。同時傳遞給completion的 rc參數爲: ZOK 操作完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點;ZINVALIDACL 非法 ACL;ZBADVERSION 版本號不匹配。
datacompletion 函數被調用時,傳遞給 completion 的數據。

 

  • 異步批處理 API
ZOOAPI int zoo_amulti(zhandle_t * zh, int count, const zoo_op_t * ops,
                      zoo_op_result_t * results, void_completion_t,
                      const void *data);

異步批處理與同步批處理方式類似見《Zookeeper C API 指南五(同步 API 介紹)》,只是需要額外設置一個 void_completion_t 回調函數,在此不再贅述。

發佈了211 篇原創文章 · 獲贊 514 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章