-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Struggling with watches #25
Comments
CuratorListener is a catch-all event queue. event.getPath() is only non-null when you called watched() on one of the builders. i.e.
|
Not quite sure what you're saying there, Jordan. Not sure why my CuratorListener should ever get a CuratorEventType.WATCHED event with a null path. But it's not important, I can ignore it. My #2 is wrong. If I correctly set a checkExists().watched(), then I do in fact see the WatchedEvent.NodeCreated ZK event. My mistake. So, my only remaining question is why I never see anything but null from getData(). When a new node is created, or its data is updated, shouldn't getData() be returning the data for that node? Thanks. |
It shouldn't. Maybe there's a bug. What operation were you watching when it happened? |
You will only ever get a value getData() if you make a background getData call:
|
Yep, that's what I was missing. Thanks so much, Jordan. |
Sorry for the reopen, but event.getStat() always returns null for me, with or without inBackground(). |
I'll try to document CuratorEvent better. I get the idea that you're expecting all the fields to always return a value. That's not how it works. The CuratorEvent is a Composite of all possible events and callbacks that ZooKeeper offers. Only the methods that correspond to a particular callback or event are active. i.e., for a background getData call, CuratorEvent.getData() and CuratorEvent.getPath() will have values. For a watched getChildren call, CuratorEvent.getChildren() will have a value, etc. You might be better off setting explicit watchers, background handlers instead of using the CuratorListener. If you explain your use-case I can provide more details. |
Yes, I'll switch to watcher with callbacks -- which I have from my own implementation with the ZK client. Was hoping I could simplify things a bit with the CuratorListener. Thanks for the help. |
If you describe what you're trying to do I might be able to suggest something. |
FYI - if you want an example of how to use CuratorListener, have a look at PathChildrenCache.java |
Looking at PathChildrenCache.java, I think you're right, that's not what I want. So let me describe the simplest use case. I start with this: client.getData().watched().inBackground().forPath("/abc"); znode "/abc" exists. I go into the ZK client (zkCli.sh) and set the data for "/abc" to some new value. When the watch triggers in my curator client I want to see (1) the new data and (2) the Stat object for "/abc". How do I do that without making a subsequent get call on "/abc"? Using the CuratorListener, all I seem to get in the CuratorEvent object is the data, not the Stat object (which is always null). Thanks again. |
Unfortunately, ZooKeeper doesn't support that behavior. When the watch gets triggered, you only know that data has changed but not what the data is. ZooKeeper requires an additional call to get the data. |
Right. I was hoping/dreaming that Curator was in some way abstracting that away for me. So, I've got a znode I want to continuously watch, resetting the watch every time it triggers. With the ZK native client, I do a get/watch, receive the data/Stat object in an async callback (processResult()) and get notified of the triggered watch in a Watcher's process() callback, where I do another get/watch...and it all repeats. In curator then, I'd reproduce this with a BackgroundCallback (processResult) and a Watcher that I register with the client? |
You should use PathChildrenCache. It was written to solve the exact scenario you describe. |
It does :) Curator is focused on providing recipes. PathChildrenCache does exactly what you want. |
D'oh. Don't I feel stupid circling around again to PathChildrenCache. I obviously didn't look at it very deeply previously. Sorry about that. Can you explain a little about the "false positives" and "false negatives" comments on that class? |
It's a warning that the PathChildrenCache is never transactionally consistent - only because ZooKeeper doesn't provide this guarantee. It's only eventually consistent. |
P.S. My goal is that most users never have to look beyond the recipes. |
I've spent a lot of time on the wiki and somehow never clicked on the Utils link on the recipes page. All this time we've been discussing PathChildrenCache, I was in the source. I'll learn, eventually. This probably goes without saying, but Curator and its recipes are a distributed developer's dream come true. I'm grateful for the work you've put in on it, and for Netflix's making it Apache licensed. It's a thing of beauty. |
Hmm - I'll add a link to it on the recipes pages. |
blush thanks |
Using a PathChilidrenCache, CACHE_DATA mode... My ZK tree looks like this: /base/a, base/b, base/c When I delete /base/a I get a CHILD_UPDATED for /base/b and base/c (in addition to the CHILD_REMOVED for /base/a). Same with create. When I recreate /base/a, I get a CHILD_UPDATED on all the other children. Intentional? |
Probably not - if you don't mind, please open another issue with this. |
So this might be a noob question. But I wrote a small test here: https://gist.github.com/1886760. The thing I realized that the Assert statements always fails is because the events are only ordered, but there delivery might not always be. Which leads me to believe we should progarm around the idea of eventual consistency. Because I always will receive the last event. |
ZooKeeper watchers are single fire. (see http://zookeeper.apache.org/doc/r3.4.3/zookeeperProgrammers.html#sc_WatchGuarantees). So, I assume that your actual count is 1. Once a watcher is called, you must re-set the watch to have it called again. The only way to re-set a watch is to make another ZooKeeper call (checkExists(), etc.). |
Hi, |
umabisht - can you give more context please? If the node doesn't exist you get |
Ok, Actually i have a structure built at Zookeeper i.e /SecurityTest_NA/...../last_node(data=2) Now inmy code, where i have initialized framework like this. CuratorFramework framework =CuratorFrameworkFactory.newClient("localhost:2181",30000,10000,new RetryOneTime(10)); 1- framework.getData().inBackground().forPath(pathtilllastnode).toString(); gives null |
just to add to it , i am using Curator version 1.0.9 with ZooKeeper 3.3.1. |
ZooKeeper APIs have two modes, foreground/synchronous and background/asynchronous. In your example #1 you're using the background mode so the forPath() method returns null. The result comes through the default listener. You can also, optionally, pass a callback to receive the result. |
just to add to it , i am using Curator version 1.0.9 with ZooKeeper 3.3.1. Why? |
Yeah use the latest versions, atleast use 3.3.4 which is compatible. It had lot of important bug fixes. |
Migrating our existing system from 3.3.1 to higher versions is in planning phase and hopefully will be achieved soon.Meanwhile we chose to work with curator api and had to select version 1.0.9 to overcome compatibility issues. |
I dont understand. "Curator 1.0.x will stay compatible with ZooKeeper 3.3.x - NOTE: Now end of life and no longer maintained" |
Curator 1.0.x is at 3.3.5 now. I added the note because I'd like folks to move to the main branch. But, I'll be releasing 1.0.x versions for another month or so. |
Hi there. I'm having some problems with surfacing watches in CuratorListener.
I'll work on creating unit tests that demonstrates this, but would be grateful if you could point me at code that shows me I'm wrong.
Thanks.
The text was updated successfully, but these errors were encountered: