hadoop-zookeeper-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ted Dunning <ted.dunn...@gmail.com>
Subject Re: zookeeper.getChildren asynchronous callback
Date Thu, 11 Jun 2009 20:39:56 GMT
One way to deal with this is to wrap the getchildren call with an object
that maintains a list of watchers.  Then you can have just one watch set
which notifies all of the listener.  This single object can keep resetting
the watch each time there is a change unless you tell it otherwise.  Keeping
a boolean in this object would allow you to remember whether to keep setting
the watch.  Adding a close() method to clear the listener list and stop
resets would also help.

By concentrating the watch handling into a single place, you should be able
to get control over tihs process.  You can't turn it off quite as quickly as
if you could cancel the watch, but the effect is nearly the same.

Another trick is that you can isolate the watch in question to a special
session.  Closing that session will eliminate the watch (and all other
watches in that same session).

On Thu, Jun 11, 2009 at 10:14 AM, Satish Bhatti <cthd2001@gmail.com> wrote:

> That's right Ben.  Basically, I would like to use it something like this:
> public boolean waitForChildrenChanged( String rootPath,
>                                                           long timeout )
> {
>    BooleanLock blChildrenChanged = new BooleanLock();
>
>    Watcher tempWatcher =
>        new Watcher()
>        {
>            public void process( WatchedEvent event )
>            {
>                logger.debug( "waitForAnyEntry(): Got state event: " +
> ZooKeeperUtils.watchedEventToString( event ) );
>                blChildrenChanged.setValue( true );
>            }
>        };
>
>    zookeeper.getChildren( rootPath, watcher,
>
>        new AsyncCallback.ChildrenCallback()
>        {
>            public void processResult( int rc, String path, Object ctx,
> List<String> children )
>            {
>                logger.debug( "waitForChildrenChanged():
> AsyncCallback.ChildrenCallback(): " + rc + ", " + path + ", " + ctx + ", "
> +
> children );
>            }
>        }, null );
>
>    blChildrenChanged.waitUntilTrue( timeout );
>
>    zookeeper.removeWatch( tempWatcher );
>
>    return blChildrenChanged.isTrue();
> }
>
> The only piece missing from the API is the   zookeeper.removeWatch(
> tempWatcher );
>
> Satish
>
>
> On Thu, Jun 11, 2009 at 7:09 AM, Benjamin Reed <breed@yahoo-inc.com>
> wrote:
>
> > just to clarify i believe you are talking about callbacks on the watch
> > object you are passing in the asynchronous call rather than the
> asynchronous
> > completion callback. (Henry is making the same assumption.) when you say
> you
> > are getting the callback 10 times, i believe your are talking about 10
> > different watch objects getting called back once each. right?
> >
> > it turns out that the zookeeper client does know what you are watching,
> and
> > the zookeeper server will only register one watch. the thing that is
> missing
> > is the clearWatches call that Henry refers to. the thing that complicates
> > things a bit, perhaps not for you, is the scenario where we have
> different
> > modules sharing the same zookeeper handle. if different modules are
> > interested in watching the same object, you don't want one module to
> simply
> > clear a the watches for a path because one module may mess up the other.
> >
> > we have talked about adding this ability to clear watches for a while. i
> > think the auto-watch reregistration patch made the issue slightly more
> > pressing since it means that watches can survive for the entire lifetime
> of
> > a session not just for the duration of a connection to a specific server.
> > i've created ZOOKEEPER-442 to track this issue.
> >
> > ben
> >
> >
> > Henry Robinson wrote:
> >
> >> Hi Satish -
> >>
> >> As you've found out, you can set multiple identical watches per znode -
> >> the
> >> zookeeper client will not detect identical watches in case you really
> >> meant
> >> to call them several times. There's no way currently, as far as I know,
> to
> >> clear the watches once they've been set. So your options are either to
> >> avoid
> >> repeatedly setting them by detecting whether getChildren is a repeat
> call,
> >> or by dealing with multiple invocations on the callback path and not
> doing
> >> anything once you've established you're no longer interested.
> >>
> >> It might well make sense to add a clearWatches(path) call to the API,
> >> which
> >> would be useful particularly for clients where callbacks are expensive
> and
> >> require a context switch (which I think is true for all clients right
> >> now!).
> >>
> >> Henry
> >>
> >> On Wed, Jun 10, 2009 at 8:05 PM, Satish Bhatti <cthd2001@gmail.com>
> >> wrote:
> >>
> >>
> >>
> >>> I am using the asynchronous (callback) version of
> >>> zookeeper.getChildren().
> >>>  That call returns immediately, I then wait for a certain time interval
> >>> for
> >>> nodes to appear, and if not I exit the method that made the
> >>> zookeeper.getChildren()
> >>> call.  Later on, a node gets added under that node and I see in my
> >>> logfile
> >>> that the Watcher.process() callback that I set above gets called.  Now
> if
> >>> I
> >>> make 10 failed attempts to get a node using the above technique, and at
> >>> some
> >>> later time a node does get added, I see in the logfile that the
> >>> Watcher.process() ends up being called 10 times!  Of course by this
> time
> >>> I
> >>> have totally lost interest in those callbacks.  Question:  Is there a
> way
> >>> to
> >>> remove that asynchronous callback?  i.e. If I make a asynchronous
> >>> zookeeper.getChildren()
> >>> call, wait time t, give up, at that point can I remove the async
> >>> callback?
> >>> Satish
> >>>
> >>>
> >>>
> >>
> >
>



-- 
Ted Dunning, CTO
DeepDyve

111 West Evelyn Ave. Ste. 202
Sunnyvale, CA 94086
http://www.deepdyve.com
858-414-0013 (m)
408-773-0220 (fax)

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message