>
>
> The best place for help I was able to find is ``help(zookeeper)`` --
> is there somewhere else I should be looking instead? It looks like you
> wrapped the c client, so I also have been looking in zookeeper.h and
> trying to infer what's going on.
>
>
zookeeper.h is helpful because, as you say, the Python bindings wrap the C
library so the calls and parameters are similar. There is a README bundled
with the zkpython code but that is very light on detail! You can also read
the source code of the library itself - after ZOOKEEPER-631 gets committed,
this should be more useful than the version released with 3.3.0.
None of these are any substitute for good documentation, however. I've
created https://issues.apache.org/jira/browse/ZOOKEEPER-745 for the purpose
of tracking improved documentation, and any contributions or suggestions you
want to make on that JIRA would be really appreciated!
> > Does this help at all? Let me know if you have any follow on questions.
>
> Very much so! If I cleanup the sample code below would you want to put
> this on a wiki or check in as an example? Would have been nice if
> someone already figured this out when I started messing with things :)
>
>
I think it could be very useful as part of the documentation effort - that
would be great!
cheers,
Henry
> --travis
>
>
> >
> > cheers,
> > Henry
> >
> > On 20 April 2010 23:33, Travis Crawford <traviscrawford@gmail.com>
> wrote:
> >
> > > Hey zookeeper gurus -
> > >
> > > I'm getting started with Zookeeper and the python client and an curious
> if
> > > I'm structuring watches correctly. I'd like to watch a znode and do
> stuff
> > > when its children change. Something doesn't feel right about having two
> > > methods: one to handle the actual get children call, and one to handle
> the
> > > watch.
> > >
> > > Does this seem like the right direction? If not, any suggestions on how
> to
> > > better structure things?
> > >
> > >
> > > #!/usr/bin/python
> > >
> > > import signal
> > > import threading
> > > import zookeeper
> > >
> > > import logging
> > > logger = logging.getLogger()
> > >
> > > from optparse import OptionParser
> > > options = None
> > > args = None
> > >
> > >
> > > class ZKTest(threading.Thread):
> > > zparent = '/home/travis/zktest'
> > >
> > > def __init__(self):
> > > threading.Thread.__init__(self)
> > > if options.verbose:
> > > zookeeper.set_debug_level(zookeeper.LOG_LEVEL_DEBUG)
> > > self.zh = zookeeper.init(options.servers)
> > > zookeeper.aget_children(self.zh, self.zparent, self.watcher,
> > > self.handler)
> > >
> > > def __del__(self):
> > > zookeeper.close(self.zh)
> > >
> > > def handler(self, rc, rc1, children):
> > > """Handle zookeeper.aget_children() responses.
> > >
> > > Args:
> > > Arguments are not documented well and I'm not entirely sure what
> to
> > > call these. ``rc`` appears to be the response code, such as OK.
> > > However, the only possible mapping of 0 is OK, so in successful
> cases
> > > there appear to be two response codes. The example with no
> children
> > > returned ``rc1`` of -7 which maps to OPERATIONTIMEOUT so that
> appears
> > > to be an error code, but its not clear what was OK in that case.
> > >
> > > If anyone figures this out I would love to know.
> > >
> > > Example args:
> > > 'args': (0, 0, ['a', 'b'])
> > > 'args': (0, -7, [])
> > >
> > > Does not provide a return value.
> > > """
> > > logger.debug('Processing response: (%d, %d, %s)' % (rc, rc1,
> children))
> > > if (zookeeper.OK == rc and zookeeper.OK == rc1):
> > > logger.debug('Do the actual work here.')
> > > else:
> > > logger.debug('Error getting children! Retrying.')
> > > zookeeper.aget_children(self.zh, self.zparent, self.watcher,
> > > self.handler)
> > >
> > > def watcher(self, rc, event, state, path):
> > > """Handle zookeeper.aget_children() watches.
> > >
> > > This code is called when an child znode changes and triggers a child
> > > watch. It is not called to handle the aget_children call itself.
> > >
> > > Numeric arguments map to constants. See ``DATA`` in
> ``help(zookeeper)``
> > > for more information.
> > >
> > > Args:
> > > rc Return code.
> > > event Event that caused the watch (often called ``type``
> elsewhere).
> > > stats Connection state.
> > > path Znode that triggered this watch.
> > >
> > > Does not provide a return value.
> > > """
> > > logger.debug('Child watch: (%d, %d, %d, %s)' % (rc, event, state,
> path))
> > > zookeeper.aget_children(self.zh, self.zparent, self.watcher,
> > > self.handler)
> > >
> > > def run(self):
> > > while True:
> > > pass
> > >
> > >
> > > def main():
> > > # Allow Ctrl-C
> > > signal.signal(signal.SIGINT, signal.SIG_DFL)
> > >
> > > parser = OptionParser()
> > > parser.add_option('-v', '--verbose',
> > > dest='verbose',
> > > default=True,
> > > action='store_true',
> > > help='Verbose logging. (default: %default)')
> > > parser.add_option('--servers',
> > > dest='servers',
> > > default='localhost:2181',
> > > help='Comma-separated list of host:port pairs. (default: %default)')
> > > global options
> > > global args
> > > (options, args) = parser.parse_args()
> > >
> > > if options.verbose:
> > > logger.setLevel(logging.DEBUG)
> > > else:
> > > logger.setLevel(logging.INFO)
> > > formatter = logging.Formatter("%(asctime)s %(filename)s:%(lineno)d -
> > > %(message)s")
> > > stream_handler = logging.StreamHandler()
> > > stream_handler.setFormatter(formatter)
> > > logger.addHandler(stream_handler)
> > >
> > > zktest = ZKTest()
> > > zktest.daemon = True
> > > zktest.start()
> > >
> > >
> > > if __name__ == '__main__':
> > > main()
> > >
> > >
> > > Thanks!
> > > Travis
> > >
> >
> >
> >
> > --
> > Henry Robinson
> > Software Engineer
> > Cloudera
> > 415-994-6679
>
--
Henry Robinson
Software Engineer
Cloudera
415-994-6679
|