Ejemplo n.º 1
0
    def reject(self, _: Exception) -> None:
        """See: :meth:`~aRx.abstract.promise.Promise.reject` for more information.
        
        Raises:
            InvalidStateError: Chained promises aren't allowed to be resolved externally.

        """
        raise InvalidStateError("Chain promise can't be rejected externally")
Ejemplo n.º 2
0
 def run_in_loop(self, func, timeout: float = 30.0):
     """
     Schedule a normal function or coroutine function to be run on the event loop, and block
     until the function has returned.
     """
     # TODO: the awful awful witchcraft required to remove these checks
     if self.loop is None:
         raise InvalidStateError("loop must be set before calling these methods")
     return execute_in_loop(self.loop, func, timeout=timeout)
Ejemplo n.º 3
0
 async def _wrap(*args, **kwargs):
     if not calls:
         calls.append(None)
         try:
             return await async_fn(*args, **kwargs)
         finally:
             calls.pop()
     else:
         raise InvalidStateError("calls to %r cannot be re-entrant", async_fn)
Ejemplo n.º 4
0
    def run_in_executor(self, func):
        """
        Schedule a normal function to be run on a background thread, and yield until the function
        has returned.
        """
        # TODO: the awful awful witchcraft required to remove these checks
        if self.loop is None or self.executor is None:
            raise InvalidStateError("loop must be set before calling these methods")

        return self.loop.run_in_executor(self.executor, func)
Ejemplo n.º 5
0
 def cmd_future_finished(_):
     ret = cmd_fut.result()
     if ret is None:
         fut.set_result(None)
     elif isinstance(ret, (CommandBuilder, Command, list, tuple)):
         propagate(ensure_future(submit_fn(ret)), fut)
     elif inspect.isawaitable(ret):
         LOG.error('A callback cannot return an Awaitable of an Awaitable')
         raise InvalidStateError(
             'A callback cannot return an Awaitable of an Awaitable')
Ejemplo n.º 6
0
 async def stop(self) -> None:
     """
     Stop the underlying ACS stream. After this point, the stream is considered inoperable.
     """
     if self._task is not None:
         self._task.cancel()
         self._task = None
         self._state = STOPPED
     else:
         raise InvalidStateError("this ACS has already been stopped")
Ejemplo n.º 7
0
	def set_result(self, result):
		"""Mark the future done and set its result.

		If the future is already done when this method is called, raises
		InvalidStateError.
		"""
		if self._state != _PENDING:
			raise InvalidStateError('{}: {!r}'.format(self._state, self))
		self._result = result
		self._state = _FINISHED
		self._schedule_callbacks()
Ejemplo n.º 8
0
    def fire(self, arg, exc=None, **kwargs):
        '''The callback handlers registered via the :meth:~AbstractEvent.bind`
        method are executed first.

        :param arg: the argument
        :param exc: optional exception
        '''
        if self._fired:
            raise InvalidStateError('already fired')
        self._fired = 1
        self._process(arg, exc, kwargs)
        return self
Ejemplo n.º 9
0
	def exception(self):
		"""Return the exception that was set on this future.

		The exception (or None if no exception was set) is returned only if
		the future is done.  If the future has been cancelled, raises
		CancelledError.  If the future isn't done yet, raises
		InvalidStateError.
		"""
		if self._state == _CANCELLED:
			raise CancelledError
		if self._state != _FINISHED:
			raise InvalidStateError('Exception is not set.')
		return self._exception
Ejemplo n.º 10
0
	def set_exception(self, exception):
		"""Mark the future done and set an exception.

		If the future is already done when this method is called, raises
		InvalidStateError.
		"""
		if self._state != _PENDING:
			raise InvalidStateError('{}: {!r}'.format(self._state, self))
		if isinstance(exception, type):
			exception = exception()
		self._exception = exception
		self._state = _FINISHED
		self._schedule_callbacks()
Ejemplo n.º 11
0
    def set_loop(self, loop: AbstractEventLoop) -> None:
        """
        Set the loop affinity for this future.

        It is an error to call this function more than once with different values for the loop.

        :param loop:
        """
        with self._lock:
            if self.__loop is None:
                self.__loop = loop
            elif self.__loop is not loop:
                raise InvalidStateError("This future is already associated with a specific loop.")
Ejemplo n.º 12
0
    def run_in_executor(self, func: 'Callable[[], T]') -> Awaitable[T]:
        """
        Schedule a normal function to be run on a background thread, and yield until the function
        has returned.
        """
        # TODO: the awful awful witchcraft required to remove these checks
        if self._loop is None or self._executor is None:
            raise InvalidStateError(
                'loop must be set before calling these methods')

        # for some reason, PyCharm doesn't seem to like this type so make an explicit cast
        return cast(Awaitable[T],
                    self._loop.run_in_executor(self._executor, func))
Ejemplo n.º 13
0
    def result(self) -> T:
        """Return the result of the Task.

        If the Task ran to completion, the result is returned.
        If the Task failed with an exception, the exception is re-raised.
        If the Task was cancelled, the CancelledError is re-raised.
        If the coroutine is not yet complete, a :exc:`asyncio.InvalidStateError` is raised.
        """
        if not self.done():
            raise InvalidStateError("result is not yet available")
        elif self.cancelled():
            raise self._cancelled
        else:
            return self._outcome.get()
Ejemplo n.º 14
0
    async def start(self) -> None:
        """
        Have the ACS start subscribing for events from the server. This coroutine "blocks" until a
        snapshot is available.
        """
        if self._state != NOT_STARTED:
            raise InvalidStateError("this ACS is already running")

        # ensure that we "start" our read before we even connect to the stream, so that we can be
        # sure the future is triggered on the very first read
        fut = self.read()
        self._state = CONNECTING
        self._task = ensure_future(self._main())
        await fut
Ejemplo n.º 15
0
	def result(self):
		"""Return the result this future represents.

		If the future has been cancelled, raises CancelledError.  If the
		future's result isn't yet available, raises InvalidStateError.  If
		the future is done and has an exception set, this exception is raised.
		"""
		if self._state == _CANCELLED:
			raise CancelledError()
		if self._state != _FINISHED:
			raise InvalidStateError('Result is not ready.')
		if self._exception is not None:
			raise self._exception
		return self._result
Ejemplo n.º 16
0
    def read(self) -> "Awaitable[Snapshot]":
        """
        Returns a snapshot of data.

        Despite being asynchronous, this call will generally return immediately unless:
        * :meth:`start` has not yet been called
        * the stream is still reading the initial Active Contract Set
        """
        if self._state == STOPPED:
            raise InvalidStateError("this ACS has already been cancelled")

        if self._snapshot_fut is None:
            self._snapshot_fut = get_event_loop().create_future()
        return self._snapshot_fut
Ejemplo n.º 17
0
    def exception(self) -> typing.Optional[BaseException]:
        """Return the exception of the Task.

        If the Task ran to completion, ``None`` is returned.
        If the Task failed with an exception, the exception is returned.
        If the Task was cancelled, the CancelledError is re-raised.
        If the coroutine is not yet complete, a :exc:`asyncio.InvalidStateError` is raised.
        """
        if not self.done():
            raise InvalidStateError("result is not yet available")
        elif self.cancelled():
            raise self._cancelled
        elif isinstance(self._outcome, outcomes.Error):
            return self._outcome.error
        else:
            return None
Ejemplo n.º 18
0
    async def connect(self):
        if self.disconnect_future is not None:
            raise InvalidStateError('already connected')
        self.disconnect_future = asyncio.Future()

        try:
            self._client = await websockets.connect(self._WS_URL)

            # if auth class was passed into websocket class
            # we need to emit authenticated requests
            if self._isPrivate:
                await self.login()
                self.tasks.append(asyncio.create_task(self._ping_loop()))

            return self._client
        except Exception as e:
            self.logger().error(f"Websocket error: '{str(e)}'", exc_info=True)
Ejemplo n.º 19
0
    def notify(self, event: 'BaseEvent') -> 'Awaitable[None]':
        """
        Notifies handler(s) associated with this bot that the given event has occurred. Note that
        this notification is asynchronous: in other words, event handlers will not have processed
        this event by the time this function returns.

        :param event: The event to raise.
        """
        if not isinstance(event, BaseEvent):
            raise ValueError('expected a BaseEvent')

        if self._queue is None:
            raise InvalidStateError('Cannot notify on a bot whose main method is not running')
        bot_invocation = BotInvocation(event)
        self._queue.append(bot_invocation)
        if self._signal is not None:
            self._signal.notify_all()
        return bot_invocation.future
Ejemplo n.º 20
0
    def set_exception(self, exception):
        """Mark the future done and set an exception.

        If the future is already done when this method is called, raises
        InvalidStateError.
        """
        with self._lock:
            if self._state != _PENDING:
                raise InvalidStateError('{}: {!r}'.format(self._state, self))
            if isinstance(exception, type):
                exception = exception()
            if type(exception) is StopIteration:
                raise TypeError(
                    "StopIteration interacts badly with generators "
                    "and cannot be raised into a Future")
            self._exception = exception
            self._state = _FINISHED
            self._schedule_callbacks()
            self._log_traceback = True
Ejemplo n.º 21
0
 def onTaskDone(task):
     """Task done handler to publish complete (success) & critical (fail) events"""
     try:
         err = task.exception()
         if (err):
             self.emit("critical", err)
         else:
             result = task.result()
             self.emit("complete", result)
     except CancelledError as err:
         self.emit(
             "warning",
             CancelledError("onTaskDone called after task cancelled").
             with_traceback(err.__traceback__))
         LOGGER.warning("Shouldn't see onTaskDone when cancelled??")
     except InvalidStateError as err:
         self.emit(
             "error",
             InvalidStateError(
                 "onTaskDone called before task finished: Risk of zombie task"
             ).with_traceback(err.__traceback__))
Ejemplo n.º 22
0
    def release(self, blocking=True, timeout=10):
        """
        Release a hold on the lock to allow another holder. Note that
        while Python's threading.Lock does not have options for blocking
        or timeout in release(), this lock uses a threading.Lock
        internally and so will need to acquire that lock in order
        to properly synchronize the underlying state.
        :param blocking : bool will bock if True
        :param timeout : a timeout (in seconds) to wait for the lock
                         before failing.
        :return : True if lock was released successfully, False otherwise.
        """

        if self.current_tasks == 0:
            raise InvalidStateError("Cannot release lock when no "
                                    "concurrent tasks are executing")

        lock_acquired = self.lock.acquire(blocking, timeout)
        if lock_acquired:
            self.current_tasks -= 1
            self.lock.release()
        return lock_acquired
Ejemplo n.º 23
0
    def read_immediately(self) -> "Optional[Snapshot]":
        """
        Returns the most recent snapshot of data, or ``None`` if this ACS was never started.

        This can be used as an alternative to :meth:`read` when the caller more interested in a
        non-``async`` call, and can tolerate reading data that is potentially slightly behind (or
        not yet present).

        :return: The last good ``Snapshot``, or ``None`` if the stream has not yet been started.
        :raises InvalidStateError: if the stream has already been stopped
        """
        if self._state == STOPPED:
            raise InvalidStateError("this ACS has already been cancelled")

        # if our Snapshot future is in a failed state, this method also throws in order to make
        # any read() exceptions known
        if self._snapshot_fut is not None:
            ex = self._snapshot_fut.exception()
            if ex is not None:
                raise ex

        return self._snapshot
Ejemplo n.º 24
0
 def result(self):
     # 获取future 的结果
     if self.status != self._FINISHED:
         raise InvalidStateError('future is not ready')
     return self._result