> > > 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 <traviscrawf...@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