Exemplo n.º 1
0
class Values(object):
    # helper to collect multiple values; ignore errors unless nothing has succeeded
    # QQQ could probably be moved somewhere - hub.py?

    __slots__ = ['count', 'values', 'error', 'waiter']

    def __init__(self, hub, count):
        self.count = count
        self.values = []
        self.error = None
        self.waiter = Waiter(hub)

    def __call__(self, source):
        self.count -= 1
        if source.exception is None:
            self.values.append(source.value)
        else:
            self.error = source.exception
        if self.count <= 0:
            self.waiter.switch()

    def get(self):
        self.waiter.get()
        if self.values:
            return self.values
        else:
            raise self.error
Exemplo n.º 2
0
class Values(object):
    # helper to collect multiple values; ignore errors unless nothing has succeeded
    # QQQ could probably be moved somewhere - hub.py?

    __slots__ = ['count', 'values', 'error', 'waiter']

    def __init__(self, hub, count):
        self.count = count
        self.values = []
        self.error = None
        self.waiter = Waiter(hub)

    def __call__(self, source):
        self.count -= 1
        if source.exception is None:
            self.values.append(source.value)
        else:
            self.error = source.exception
        if self.count <= 0:
            self.waiter.switch()

    def get(self):
        self.waiter.get()
        if self.values:
            return self.values
        else:
            assert error is not None
            raise self.error  # pylint:disable=raising-bad-type
Exemplo n.º 3
0
class Values(object):
    # helper to collect multiple values; ignore errors unless nothing has succeeded
    # QQQ could probably be moved somewhere - hub.py?

    __slots__ = ["count", "values", "error", "waiter"]

    def __init__(self, hub, count):
        self.count = count
        self.values = []
        self.error = None
        self.waiter = Waiter(hub)

    def __call__(self, source):
        self.count -= 1
        if source.exception is None:
            self.values.append(source.value)
        else:
            self.error = source.exception
        if self.count <= 0:
            self.waiter.switch()

    def get(self):
        self.waiter.get()
        if self.values:
            return self.values
        else:
            assert error is not None
            raise self.error  # pylint:disable=raising-bad-type
Exemplo n.º 4
0
class Values(object):
    # helper to collect multiple values; ignore errors unless nothing has succeeded
    # QQQ could probably be moved somewhere - hub.py?

    __slots__ = ['count', 'values', 'error', 'waiter', '_synced']

    def __init__(self, hub, count):
        self.count = count
        self.values = []
        self.error = None
        self.waiter = Waiter(hub)
        self._synced = False

    def __call__(self, source):
        self.count -= 1
        if source.exception is None:
            self.values.append(source.value)
        else:
            self.error = source.exception
        if self.count <= 0:
            self.waiter.switch()

    def get(self, throw_on_error=True):
        if not self._synced:
            self.waiter.get()
            self._synced = True
        if self.values or not throw_on_error:
            return self.values
        else:
            assert error is not None
            raise self.error # pylint:disable=raising-bad-type
Exemplo n.º 5
0
class GView(AsyncViewBase):
    def __init__(self, *args, **kwargs):
        """
        Subclass of :class:`~couchbase.async.view.AsyncViewBase`
        This doesn't expose an API different from the normal synchronous
        view API. It's just implemented differently
        """
        super(GView, self).__init__(*args, **kwargs)

        # We use __double_underscore to mangle names. This is because
        # the views class has quite a bit of data attached to it.
        self.__waiter = Waiter()
        self.__iterbufs = deque()
        self.__done_called = False

    def raise_include_docs(self):
        # We allow include_docs in the RowProcessor
        pass

    def _callback(self, *args):
        # Here we need to make sure the callback is invoked
        # from within the context of the calling greenlet. Since
        # we're invoked from the hub, we will need to issue more
        # blocking calls and thus ensure we're not doing the processing
        # from here.
        self.__waiter.switch(args)

    def on_rows(self, rows):
        self.__iterbufs.appendleft(rows)

    def on_error(self, ex):
        raise ex

    def on_done(self):
        self.__done_called = True

    def __wait_rows(self):
        """
        Called when we need more data..
        """
        args = self.__waiter.get()
        super(GView, self)._callback(*args)

    def __iter__(self):
        if not self._do_iter:
            raise AlreadyQueriedError.pyexc("Already queried")

        while self._do_iter and not self.__done_called:
            self.__wait_rows()
            while len(self.__iterbufs):
                ri = self.__iterbufs.pop()
                for r in ri:
                    yield r

        self._do_iter = False
class GView(AsyncViewBase):
    def __init__(self, *args, **kwargs):
        """
        Subclass of :class:`~couchbase.async.view.AsyncViewBase`
        This doesn't expose an API different from the normal synchronous
        view API. It's just implemented differently
        """
        super(GView, self).__init__(*args, **kwargs)

        # We use __double_underscore to mangle names. This is because
        # the views class has quite a bit of data attached to it.
        self.__waiter = Waiter()
        self.__iterbufs = deque()
        self.__done_called = False

    def raise_include_docs(self):
        # We allow include_docs in the RowProcessor
        pass

    def _callback(self, *args):
        # Here we need to make sure the callback is invoked
        # from within the context of the calling greenlet. Since
        # we're invoked from the hub, we will need to issue more
        # blocking calls and thus ensure we're not doing the processing
        # from here.
        self.__waiter.switch(args)

    def on_rows(self, rows):
        self.__iterbufs.appendleft(rows)

    def on_error(self, ex):
        raise ex

    def on_done(self):
        self.__done_called = True

    def __wait_rows(self):
        """
        Called when we need more data..
        """
        args = self.__waiter.get()
        super(GView, self)._callback(*args)

    def __iter__(self):
        if not self._do_iter:
            raise AlreadyQueriedError.pyexc("Already queried")

        while self._do_iter and not self.__done_called:
            self.__wait_rows()
            while len(self.__iterbufs):
                ri = self.__iterbufs.pop()
                for r in ri:
                    yield r

        self._do_iter = False
Exemplo n.º 7
0
class GRowsHandler(object):
    def __init__(self):
        """
        Subclass of :class:`~.AsyncViewBase`
        This doesn't expose an API different from the normal
        synchronous view API. It's just implemented differently
        """

        # We use __double_underscore to mangle names. This is because
        # the views class has quite a bit of data attached to it.
        self.__waiter = Waiter()
        self.__raw_rows = []
        self.__done_called = False
        self.start()
        self.raw.rows_per_call = 100000

    def _callback(self, *args):
        # This method overridden from the parent. Rather than do the processing
        # on demand, we must defer it for later. This is done by copying the
        # rows to a list. In the typical case we shouldn't accumulate all
        # the rows in the buffer (since .switch() will typically have something
        # waiting for us). However if the view is destroyed prematurely,
        # or if the user is not actively iterating over us, or if something
        # else happens (such as more rows arriving during a get request with
        # include_docs), we simply accumulate the rows here.
        self.__raw_rows.append(self.raw.rows)
        if self.raw.done:
            self._clear()
        self.__waiter.switch()

    def _errback(self, mres, *args):
        self._clear()
        self.__waiter.throw(*args)

    def __iter__(self):
        if not self._do_iter:
            raise AlreadyQueriedError.pyexc("Already queried")

        while self._do_iter and not self.__done_called:
            self.__waiter.get()

            rowset_list = self.__raw_rows
            self.__raw_rows = []
            for rowset in rowset_list:
                for row in self._process_payload(rowset):
                    yield row

        self._do_iter = False
Exemplo n.º 8
0
class GRowsHandler(object):
    def __init__(self):
        """
        Subclass of :class:`~.AsyncViewBase`
        This doesn't expose an API different from the normal
        synchronous view API. It's just implemented differently
        """

        # We use __double_underscore to mangle names. This is because
        # the views class has quite a bit of data attached to it.
        self.__waiter = Waiter()
        self.__raw_rows = []
        self.__done_called = False
        self.start()
        self.raw.rows_per_call = 100000

    def _callback(self, *args):
        # This method overridden from the parent. Rather than do the processing
        # on demand, we must defer it for later. This is done by copying the
        # rows to a list. In the typical case we shouldn't accumulate all
        # the rows in the buffer (since .switch() will typically have something
        # waiting for us). However if the view is destroyed prematurely,
        # or if the user is not actively iterating over us, or if something
        # else happens (such as more rows arriving during a get request with
        # include_docs), we simply accumulate the rows here.
        self.__raw_rows.append(self.raw.rows)
        if self.raw.done:
            self._clear()
        self.__waiter.switch()

    def _errback(self, mres, *args):
        self._clear()
        self.__waiter.throw(*args)

    def __iter__(self):
        if not self._do_iter:
            raise AlreadyQueriedError.pyexc("Already queried")

        while self._do_iter and not self.__done_called:
            self.__waiter.get()

            rowset_list = self.__raw_rows
            self.__raw_rows = []
            for rowset in rowset_list:
                for row in self._process_payload(rowset):
                    yield row

        self._do_iter = False
Exemplo n.º 9
0
    def _http_request(self, **kwargs):
        res = super(Bucket, self)._http_request(**kwargs)

        w = Waiter()
        res.callback = lambda x: w.switch(x)
        res.errback = lambda x, c, o, b: w.throw(c, o, b)
        return w.get()
Exemplo n.º 10
0
    def _http_request(self, **kwargs):
        res = super(Bucket, self)._http_request(**kwargs)

        w = Waiter()
        res.callback = lambda x: w.switch(x)
        res.errback = lambda x, c, o, b: w.throw(c, o, b)
        return w.get()
Exemplo n.º 11
0
    def test(self):
        waiter = Waiter()
        self.assertEqual(str(waiter), '<Waiter greenlet=None>')
        waiter.switch(25)
        self.assertEqual(str(waiter), '<Waiter greenlet=None value=25>')
        self.assertEqual(waiter.get(), 25)

        waiter = Waiter()
        waiter.throw(ZeroDivisionError)
        assert re.match('^<Waiter greenlet=None exc_info=.*ZeroDivisionError.*$', str(waiter)), str(waiter)
        self.assertRaises(ZeroDivisionError, waiter.get)

        waiter = Waiter()
        g = gevent.spawn(waiter.get)
        gevent.sleep(0)
        assert str(waiter).startswith('<Waiter greenlet=<Greenlet at '), str(waiter)
        g.kill()
Exemplo n.º 12
0
    def test(self):
        waiter = Waiter()
        self.assertEqual(str(waiter), '<Waiter greenlet=None>')
        waiter.switch(25)
        self.assertEqual(str(waiter), '<Waiter greenlet=None value=25>')
        self.assertEqual(waiter.get(), 25)

        waiter = Waiter()
        waiter.throw(ZeroDivisionError)
        assert re.match('^<Waiter greenlet=None exc_info=.*ZeroDivisionError.*$', str(waiter)), str(waiter)
        self.assertRaises(ZeroDivisionError, waiter.get)

        waiter = Waiter()
        g = gevent.spawn(waiter.get)
        gevent.sleep(0)
        self.assertTrue(str(waiter).startswith('<Waiter greenlet=<Greenlet "Greenlet-'))

        g.kill()