def start_watching(self, cluster, callback):
logger.debug("<STR_LIT>", cluster.name)<EOL>wait_on_any(self.connected, self.shutdown)<EOL>logger.debug("<STR_LIT>")<EOL>znode_path = "<STR_LIT:/>".join([self.base_path, cluster.name])<EOL>self.stop_events[znode_path] = threading.Event()<EOL>def should_stop():<EOL><INDENT>return (<EOL>znode_path not in self.stop_events or<EOL>self.stop_events[znode_path].is_set() or<EOL>self.shutdown.is_set()<EOL>)<EOL><DEDENT>while not should_stop():<EOL><INDENT>try:<EOL><INDENT>if self.client.exists(znode_path):<EOL><INDENT>break<EOL><DEDENT><DEDENT>except exceptions.ConnectionClosedError:<EOL><INDENT>break<EOL><DEDENT>wait_on_any(<EOL>self.stop_events[znode_path], self.shutdown,<EOL>timeout=NO_NODE_INTERVAL<EOL>)<EOL><DEDENT>logger.debug("<STR_LIT>", znode_path)<EOL>@self.client.ChildrenWatch(znode_path)<EOL>def watch(children):<EOL><INDENT>if should_stop():<EOL><INDENT>return False<EOL><DEDENT>logger.debug("<STR_LIT>", znode_path)<EOL>new_nodes = []<EOL>for child in children:<EOL><INDENT>child_path = "<STR_LIT:/>".join([znode_path, child])<EOL>try:<EOL><INDENT>new_nodes.append(<EOL>Node.deserialize(self.client.get(child_path)[<NUM_LIT:0>])<EOL>)<EOL><DEDENT>except ValueError:<EOL><INDENT>logger.exception("<STR_LIT>", child)<EOL>continue<EOL><DEDENT><DEDENT>cluster.nodes = new_nodes<EOL>callback()<EOL><DEDENT>
Initiates the "watching" of a cluster's associated znode.

This is done via kazoo's ChildrenWatch object.  When a cluster's
znode's child nodes are updated, a callback is fired and we update
the cluster's `nodes` attribute based on the existing child znodes
and fire a passed-in callback with no arguments once done.

If the cluster's znode does not exist we wait for `NO_NODE_INTERVAL`
seconds before trying again as long as no ChildrenWatch exists for
the given cluster yet and we are not in the process of shutting down.