示例#1
0
文件: tornado.py 项目: tristeng/kazoo
class AsyncResult(object):
    """
    Essentially a wrapper for a Tornado TracebackFuture
    """
    def __init__(self, future=None):
        if future is not None:
            self._future = future
        else:
            self._future = TracebackFuture()
            self._future.add_done_callback(functools.partial(async_result_complete, self))
        self._condition = threading.Condition()

    def ready(self):
        """Return `True` if and only if it holds a value or an
        exception"""
        return self._future.done()

    def successful(self):
        """Return `True` if and only if it is ready and holds a
        value"""
        return self._future.exception() is None

    @property
    def exception(self):
        return self._future.exception()

    def set(self, value=None):
        """Store the value. Wake up the waiters.

        :param value: Value to store as the result.

        Any waiters blocking on :meth:`get` or :meth:`wait` are woken
        up. Sequential calls to :meth:`wait` and :meth:`get` will not
        block at all."""
        with self._condition:
            self._future.set_result(value)

    def set_exception(self, exception):
        """Store the exception. Wake up the waiters.

        :param exception: Exception to raise when fetching the value.

        Any waiters blocking on :meth:`get` or :meth:`wait` are woken
        up. Sequential calls to :meth:`wait` and :meth:`get` will not
        block at all."""
        with self._condition:
            self._future.set_exception(exception)

    def get(self, block=True, timeout=None):
        """Return the stored value or raise the exception

        :param block: Whether this method should block or return
                      immediately.
        :type block: bool
        :param timeout: How long to wait for a value when `block` is
                        `True`.
        :type timeout: float

        If this instance already holds a value / an exception, return /
        raise it immediately. Otherwise, block until :meth:`set` or
        :meth:`set_exception` has been called or until the optional
        timeout occurs."""
        with self._condition:
            if self.ready():
                return self._future.result()
            elif block:
                self._condition.wait(timeout)
                return self._future.result()

            # if we get to this point we timeout
            raise KazooTimeoutError()

    def get_nowait(self):
        """Return the value or raise the exception without blocking.

        If nothing is available, raise the Timeout exception class on
        the associated :class:`IHandler` interface."""
        return self._future.result()

    def wait(self, timeout=None):
        """Block until the instance is ready.

        :param timeout: How long to wait for a value
        :type timeout: float

        If this instance already holds a value / an exception, return /
        raise it immediately. Otherwise, block until :meth:`set` or
        :meth:`set_exception` has been called or until the optional
        timeout occurs."""
        with self._condition:
            self._condition.wait(timeout)
        return self.ready()

    def rawlink(self, callback):
        """Register a callback to call when a value or an exception is
        set

        :param callback:
            A callback function to call after :meth:`set` or
            :meth:`set_exception` has been called. This function will
            be passed a single argument, this instance.
        :type callback: func

        """
        def on_callback(future):
            callback(AsyncResult(future))

        IOLoop.current().add_future(self._future, on_callback)

    def unlink(self, callback):
        """Remove the callback set by :meth:`rawlink`

        :param callback: A callback function to remove.
        :type callback: func

        """

    def notify(self):
        self._condition.notify_all()