def start(self): """Starts the cache. The cache is not started automatically. You must call this method. After a cache started, all changes of subtree will be synchronized from the ZooKeeper server. Events will be fired for those activity. See also :meth:`~TreeCache.listen`. .. note:: This method is not thread safe. """ if self._state == self.STATE_LATENT: self._state = self.STATE_STARTED elif self._state == self.STATE_CLOSED: raise KazooException('already closed') else: raise KazooException('already started') self._client.add_listener(self._session_watcher) self._client.ensure_path(self._root._path) if self._client.connected: self._root.on_created()
def test_announcer_under_abnormal_circumstances(): mock_serverset = create_autospec(spec=ServerSet, instance=True) mock_serverset.join = MagicMock() mock_serverset.join.side_effect = [ KazooException('Whoops the ensemble is down!'), 'member0001', ] mock_serverset.cancel = MagicMock() endpoint = Endpoint('localhost', 12345) clock = ThreadedClock(31337.0) announcer = Announcer(mock_serverset, endpoint, clock=clock, exception_wait=Amount(2, Time.SECONDS)) announcer.start() try: clock.tick(1.0) assert announcer.disconnected_time() == 1.0 clock.tick(2.0) assert announcer.disconnected_time() == 0.0, ( 'Announcer should recover after an exception thrown internally.') assert announcer._membership == 'member0001' finally: announcer.stop()
def joined_side_effect(*args, **kw): # 'global' does not work within python nested functions, so we cannot use a # counter here, so instead we do append/len (see PEP-3104) operations.append(1) if len(operations) == 1 or len(operations) == 3: joined.set() return 'membership %d' % len(operations) else: raise KazooException('Failed to reconnect')
def start(self): """Starts the cache. The cache is not started automatically. You must call this method. After a cache started, all changes of subtree will be synchronized from the ZooKeeper server. Events will be fired for those activity. Don't forget to call :meth:`close` if a tree was started and you don't need it anymore, or you will leak the memory of cached nodes, even if you have released all references to the :class:`TreeCache` instance. Because there are so many callbacks that have been registered to the Kazoo client. See also :meth:`~TreeCache.listen`. .. note:: This method is not thread safe. """ if self._state == self.STATE_LATENT: self._state = self.STATE_STARTED elif self._state == self.STATE_CLOSED: raise KazooException('already closed') else: raise KazooException('already started') self._task_thread = self._client.handler.spawn(self._do_background) self._client.add_listener(self._session_watcher) self._client.ensure_path(self._root._path) if self._client.connected: # The on_created and other on_* methods must not be invoked outside # the background task. This is the key to keep concurrency safe # without lock. self._in_background(self._root.on_created)
def __call__(self, func): """Callable version for use as a decorator :param func: Function to call initially and every time the children change. `func` will be called with a single argument, the list of children. :type func: callable """ if self._used: raise KazooException( "A function has already been associated with this " "ChildrenWatch instance.") self._func = func self._used = True if self._allow_session_lost: self._client.add_listener(self._session_watcher) self._get_children() return func
def __call__(self, func): """Callable version for use as a decorator :param func: Function to call initially and every time the data changes. `func` will be called with a tuple, the value of the node and a :class:`~kazoo.client.ZnodeStat` instance. :type func: callable """ if self._used: raise KazooException( "A function has already been associated with this " "DataWatch instance.") self._func = func self._used = True self._client.add_listener(self._session_watcher) self._get_data() return func