go-zookeeper / zk

Native ZooKeeper client for Go
BSD 3-Clause "New" or "Revised" License
509 stars 130 forks source link

ChildrenW and GetW cannot listen the create event? #71

Open aruyuna9531 opened 2 years ago

aruyuna9531 commented 2 years ago

When ChildrenW and GetW try to listen an unexisting znode, although the znode will be create later, the create event and all modification of the new znode cannot trigger either ChildrenW or GetW.

It seems that only ExistsW can do this?

zhangyu0310 commented 2 years ago

Only ExistsW() can listen EventNodeCreated. You can find the rule in ZooKeeper Documentation.

Semantics of Watches We can set watches with the three calls that read the state of ZooKeeper: exists, getData, and getChildren. The following list details the events that a watch can trigger and the calls that enable them:

Created event: Enabled with a call to exists. Deleted event: Enabled with a call to exists, getData, and getChildren. Changed event: Enabled with a call to exists and getData. Child event: Enabled with a call to getChildren.

aruyuna9531 commented 2 years ago

@zhangyu0310 Thanks for docs. Seems that these interfaces can do the same thing as get path watch or ls path watch command of zkCli.sh. Is there an interface which has the same effect as addWatch path command? It can listen all of create/delete/children change/value change events, and it's not disposable, I just need it.

zhangyu0310 commented 2 years ago

You can implement function addWatch(), call ExistsW() GetW() ChildrenW() at same time. But that is usually unreasonable, because too many watches will cause performance degradation.

'one-time watch' is a feature of ZooKeeper, but it is difficult to use. We usually call watch functions actively in the watch event callback.

BTW, I think etcd is your better choice.

Hitec-at commented 2 years ago

Only ExistsW() can listen EventNodeCreated. You can find the rule in ZooKeeper Documentation.

Semantics of Watches We can set watches with the three calls that read the state of ZooKeeper: exists, getData, and getChildren. The following list details the events that a watch can trigger and the calls that enable them: Created event: Enabled with a call to exists. Deleted event: Enabled with a call to exists, getData, and getChildren. Changed event: Enabled with a call to exists and getData. Child event: Enabled with a call to getChildren.

Thanks for illustrations. I'm new to zk and after reading this issue, wondering if I want to set a watch, which gets create and delete events from children znodes that will be potentially created after watch, to a znode(parent znode), Calling ChildrenW() is not the right way? I assume Zk docs said about it(bold sentence):

getData() and exists() return information about the data of the node, whereas getChildren() returns a list of children. Thus, setData() will trigger data watches for the znode being set (assuming the set is successful). A successful create() will trigger a data watch for the znode being created and a child watch for the parent znode. A successful delete() will trigger both a data watch and a child watch (since there can be no more children) for a znode being deleted as well as a child watch for the parent znode.

hope to get your reply @zhangyu0310 ! :)

zhangyu0310 commented 2 years ago

Call ChildrenW() is right way. But you need to cache children nodes of parent znode.

e.g.

/test/A/xxx

first: get children and watch ---> /test/A ---> cache children to local

then: create ---> /test/A/newNode ---> trigger ---> get children and watch(your callback) ---> compare local cache and get children / update local cache ---> difference set is the 'newNode' ---> call create callback ---> ......

Hitec-at commented 2 years ago

Call ChildrenW() is right way. But you need to cache children nodes of parent znode.

e.g.

/test/A/xxx

first: get children and watch ---> /test/A ---> cache children to local

then: create ---> /test/A/newNode ---> trigger ---> get children and watch(your callback) ---> compare local cache and get children / update local cache ---> difference set is the 'newNode' ---> call create callback ---> ......

Thanks a lot! I try this and work by caching children nodes. My implementation: