示例#1
0
    def run(self):
        try:
            for response in self._watch_response_iterator:
                if response.created:
                    self._watch_id_callbacks[response.watch_id] = \
                        self._callback
                    self._watch_id_queue.put(response.watch_id)

                callback = self._watch_id_callbacks.get(response.watch_id)
                if callback:
                    # The watcher can be safely reused, but adding a new event
                    # to indicate that the revision is already compacted
                    # requires api change which would break all users of this
                    # module. So, raising an exception if a watcher is still
                    # alive. The caller has to create a new client instance to
                    # recover would break all users of this module.
                    if response.compact_revision != 0:
                        callback(etcd3_exceptions.RevisionCompactedError(
                            response.compact_revision))
                        self.cancel(response.watch_id)
                        continue
                    for event in response.events:
                        callback(events.new_event(event))
        except grpc.RpcError as e:
            self.stop()
            if self._watch_id_callbacks:
                for callback in self._watch_id_callbacks.values():
                    callback(e)
示例#2
0
    def _handle_response(self, rs):
        with self._lock:
            if rs.created:
                if not rs.canceled:
                    # If the new watch request has already expired then cancel the
                    # created watch right away.
                    if not self._new_watch:
                        self._cancel_no_lock(rs.watch_id)
                        return

                    if rs.compact_revision != 0:
                        self._new_watch.err = exceptions.RevisionCompactedError(
                            rs.compact_revision)
                        return

                    self._callbacks[rs.watch_id] = self._new_watch.callback
                    self._new_watch.id = rs.watch_id
                    self._new_watch_cond.notify_all()
                elif rs.cancel_reason:
                    rpc_error = grpc.RpcError()
                    rpc_error.code = lambda: grpc.StatusCode.CANCELLED
                    rpc_error.message = rs.cancel_reason
                    raise rpc_error
            callback = self._callbacks.get(rs.watch_id)

        # Ignore leftovers from canceled watches.
        if not callback:
            return

        # The watcher can be safely reused, but adding a new event
        # to indicate that the revision is already compacted
        # requires api change which would break all users of this
        # module. So, raising an exception if a watcher is still
        # alive.
        if rs.compact_revision != 0:
            err = exceptions.RevisionCompactedError(rs.compact_revision)
            _safe_callback(callback, err)
            self.cancel(rs.watch_id)
            return

        # Call the callback even when there are no events in the watch
        # response so as not to ignore progress notify responses.
        if rs.events or not (rs.created or rs.canceled):
            new_events = [events.new_event(event) for event in rs.events]
            response = WatchResponse(rs.header, new_events)
            _safe_callback(callback, response)
示例#3
0
    def _handle_response(self, rs):
        with self._lock:
            if rs.created:
                # If the new watch request has already expired then cancel the
                # created watch right away.
                if not self._new_watch:
                    self._cancel_no_lock(rs.watch_id)
                    return

                if rs.compact_revision != 0:
                    self._new_watch.err = exceptions.RevisionCompactedError(
                        rs.compact_revision)
                    return

                self._callbacks[rs.watch_id] = self._new_watch.callback
                self._new_watch.id = rs.watch_id
                self._new_watch_cond.notify_all()

            callback = self._callbacks.get(rs.watch_id)

        # Ignore leftovers from canceled watches.
        if not callback:
            return

        # The watcher can be safely reused, but adding a new event
        # to indicate that the revision is already compacted
        # requires api change which would break all users of this
        # module. So, raising an exception if a watcher is still
        # alive.
        if rs.compact_revision != 0:
            err = exceptions.RevisionCompactedError(rs.compact_revision)
            _safe_callback(callback, err)
            self.cancel(rs.watch_id)
            return

        for event in rs.events:
            _safe_callback(callback, events.new_event(event))