def watch_once_response(self, key, timeout=None, **kwargs): """ Watch a key and stop after the first response. If the timeout was specified and response didn't arrive method will raise ``WatchTimedOut`` exception. :param key: key to watch :param timeout: (optional) timeout in seconds. :returns: ``WatchResponse`` """ response_queue = queue.Queue() def callback(response): response_queue.put(response) watch_id = self.add_watch_callback(key, callback, **kwargs) try: return response_queue.get(timeout=timeout) except queue.Empty: raise exceptions.WatchTimedOut() finally: self.cancel_watch(watch_id)
def add_callback(self, key, callback, range_end=None, start_revision=None, progress_notify=False, filters=None, prev_kv=False): create_watch = etcdrpc.WatchCreateRequest() create_watch.key = utils.to_bytes(key) if range_end is not None: create_watch.range_end = utils.to_bytes(range_end) if start_revision is not None: create_watch.start_revision = start_revision if progress_notify: create_watch.progress_notify = progress_notify if filters is not None: create_watch.filters = filters if prev_kv: create_watch.prev_kv = prev_kv rq = etcdrpc.WatchRequest(create_request=create_watch) with self._lock: # Start the callback thread if it is not yet running. if not self._callback_thread: thread_name = 'etcd3_watch_%x' % (id(self), ) self._callback_thread = threading.Thread(name=thread_name, target=self._run) self._callback_thread.daemon = True self._callback_thread.start() # Only one create watch request can be pending at a time, so if # there one already, then wait for it to complete first. while self._new_watch: self._new_watch_cond.wait() # Submit a create watch request. new_watch = _NewWatch(callback) self._request_queue.put(rq) self._new_watch = new_watch # Wait for the request to be completed, or timeout. self._new_watch_cond.wait(timeout=self.timeout) self._new_watch = None # If the request not completed yet, then raise a timeout exception. if new_watch.id is None and new_watch.err is None: raise exceptions.WatchTimedOut() # Raise an exception if the watch request failed. if new_watch.err: raise new_watch.err # Wake up threads stuck on add_callback call if any. self._new_watch_cond.notify_all() return new_watch.id
def add_callback(self, key, callback, range_end=None, start_revision=None, progress_notify=False, filters=None, prev_kv=False): rq = self._create_watch_request(key, range_end=range_end, start_revision=start_revision, progress_notify=progress_notify, filters=filters, prev_kv=prev_kv) with self._lock: # Start the callback thread if it is not yet running. if not self._callback_thread: thread_name = 'etcd3_watch_%x' % (id(self), ) self._callback_thread = threading.Thread(name=thread_name, target=self._run) self._callback_thread.daemon = True self._callback_thread.start() # Only one create watch request can be pending at a time, so if # there one already, then wait for it to complete first. while self._new_watch: self._new_watch_cond.wait() # Submit a create watch request. new_watch = _NewWatch(callback) self._request_queue.put(rq) self._new_watch = new_watch try: # Wait for the request to be completed, or timeout. self._new_watch_cond.wait(timeout=self.timeout) # If the request not completed yet, then raise a timeout # exception. if new_watch.id is None and new_watch.err is None: raise exceptions.WatchTimedOut() # Raise an exception if the watch request failed. if new_watch.err: raise new_watch.err finally: # Wake up threads stuck on add_callback call if any. self._new_watch = None self._new_watch_cond.notify_all() return new_watch.id
def add_watch_callback(self, *args, **kwargs): """ Watch a key or range of keys and call a callback on every response. If timeout was declared during the client initialization and the watch cannot be created during that time the method raises a ``WatchTimedOut`` exception. :param key: key to watch :param callback: callback function :returns: watch_id. Later it could be used for cancelling watch. """ try: return self.watcher.add_callback(*args, **kwargs) except queue.Empty: raise exceptions.WatchTimedOut()
def watch_once(self, key, timeout=None, **kwargs): """ Watch a key and stops after the first event. If the timeout was specified and event didn't arrived method will raise ``WatchTimedOut`` exception. :param key: key to watch :param timeout: (optional) timeout in seconds. :returns: ``Event`` """ event_queue = queue.Queue() def callback(event): event_queue.put(event) watch_id = self.add_watch_callback(key, callback, **kwargs) try: return event_queue.get(timeout=timeout) except queue.Empty: raise exceptions.WatchTimedOut() finally: self.cancel_watch(watch_id)