def delete(self, path, version=-1, recursive=False): if not isinstance(path, six.string_types): raise TypeError("path must be a string") data_watches = [] child_watches = [] path = utils.normpath(path) with self.storage.lock: if path not in self.storage: raise k_exceptions.NoNodeError("Node %s does not exist" % (path)) path_version = self.storage[path]['version'] if version != -1 and path_version != version: raise k_exceptions.BadVersionError("Version mismatch" " (%s != %s)" % (version, path_version)) if recursive: paths = [path] children = self.storage.get_children(path, only_direct=False) for child_path in six.iterkeys(children): paths.append(child_path) else: children = self.storage.get_children(path, only_direct=False) if children: raise k_exceptions.NotEmptyError("Path %s is not-empty" " (%s children exist)" % (path, len(children))) paths = [path] paths = list(reversed(sorted(set(paths)))) with self.storage.transaction(): for path in paths: self.storage.pop(path) parents = [] for path in paths: parents.extend(self.storage.get_parents(path)) parents = list(reversed(sorted(set(parents)))) for path in parents: event = k_states.WatchedEvent( type=k_states.EventType.DELETED, state=k_states.KeeperState.CONNECTED, path=path) child_watches.append(([path], event)) for path in paths: event = k_states.WatchedEvent( type=k_states.EventType.DELETED, state=k_states.KeeperState.CONNECTED, path=path) data_watches.append(([path], event)) return (True, data_watches, child_watches)
def create(self, path, value=b"", acl=None, ephemeral=False, sequence=False, makepath=False): if not isinstance(path, six.string_types): raise TypeError("path must be a string") if not isinstance(value, six.binary_type): raise TypeError("value must be a byte string") if acl: raise NotImplementedError(_NO_ACL_MSG) data_watches = [] child_watches = [] with self.storage.lock: if sequence: path = utils.normpath(path, keep_trailing=True) else: path = utils.normpath(path, keep_trailing=False) if makepath: for parent_path in utils.partition_path(path)[0:-1]: if parent_path not in self.storage: result = self.create(parent_path) data_watches.extend(result[1]) child_watches.extend(result[2]) created, parents, path = self.storage.create( path, value=value, sequence=sequence, ephemeral=ephemeral, session_id=self.session_id) if parents: event = k_states.WatchedEvent(type=k_states.EventType.CHILD, state=k_states.KeeperState.CONNECTED, path=path) child_watches.append((parents, event)) if created: event = k_states.WatchedEvent(type=k_states.EventType.CREATED, state=k_states.KeeperState.CONNECTED, path=path) data_watches.append(([path], event)) return (path, data_watches, child_watches)
def purge(self, client): if not client.session_id: return 0 with self._client_lock: if client in self._clients: self._clients.discard(client) else: return 0 removals = [] with self.lock: for path, data in six.iteritems(self._paths): if data['ephemeral'] \ and data['ephemeral_owner'] == client.session_id: removals.append(path) data_watches = [] for path in removals: event = k_states.WatchedEvent( type=k_states.EventType.DELETED, state=k_states.KeeperState.CONNECTED, path=path) data_watches.append(([path], event)) fire_paths = [] for path in removals: parents = sorted(six.iterkeys(self.get_parents(path))) for parent_path in parents: if parent_path in fire_paths: continue fire_paths.append(parent_path) child_watches = [] for path in fire_paths: event = k_states.WatchedEvent( type=k_states.EventType.DELETED, state=k_states.KeeperState.CONNECTED, path=path) child_watches.append(([path], event)) for path in removals: del self._paths[path] self.inform(client, child_watches, data_watches, inform_self=False) return len(removals)
def run_events(): """Invoke watcher callback for each event.""" while True: event = self.watch_events.get() if event == 'exit': break delay, event_type, state, path = event if delay: time.sleep(delay) watch = watches.get((path, event_type), None) if watch: watch( states.WatchedEvent(type=event_type, state=state, path=path))
def set(self, path, value, version=-1): if not isinstance(path, six.string_types): raise TypeError("path must be a string") if not isinstance(value, six.binary_type): raise TypeError("value must be a byte string") if not isinstance(version, int): raise TypeError("version must be an int") path = utils.normpath(path) try: stat = self.storage.set(path, value, version=version) except KeyError: raise k_exceptions.NoNodeError("Node %s does not exist" % (path)) data_watches = [] child_watches = [] event = k_states.WatchedEvent(type=k_states.EventType.CHANGED, state=k_states.KeeperState.CONNECTED, path=path) data_watches.append(([path], event)) return (stat, data_watches, child_watches)