示例#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
示例#2
0
文件: greenlet.py 项目: 3ddi/gevent
    def kill(self, exception=GreenletExit, block=True, timeout=None):
        """Raise the ``exception`` in the greenlet.

        If ``block`` is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
        If block is ``False``, the current greenlet is not unscheduled.

        The function always returns ``None`` and never raises an error.

        .. note::

            Depending on what this greenlet is executing and the state of the event loop,
            the exception may or may not be raised immediately when this greenlet resumes
            execution. It may be raised an a subsequent green call, or, if this greenlet
            exits before making such a call, it may not be raised at all. As of 1.1, an example
            where the exception is raised later is if this greenlet had called ``sleep(0)``; an
            example where the exception is raised immediately is if this greenlet had called ``sleep(0.1)``.

        See also :func:`gevent.kill`.

        .. versionchanged:: 0.13.0
            *block* is now ``True`` by default.
        """
        # XXX this function should not switch out if greenlet is not started but it does
        # XXX fix it (will have to override 'dead' property of greenlet.greenlet)
        if self._start_event is None:
            self._start_event = _dummy_event
        else:
            self._start_event.stop()
        if not self.dead:
            waiter = Waiter()
            self.parent.loop.run_callback(_kill, self, exception, waiter)
            if block:
                waiter.get()
                self.join(timeout)
示例#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
示例#4
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()
示例#5
0
文件: greenlet.py 项目: 3ddi/gevent
    def kill(self, exception=GreenletExit, block=True, timeout=None):
        """Raise the ``exception`` in the greenlet.

        If ``block`` is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
        If block is ``False``, the current greenlet is not unscheduled.

        The function always returns ``None`` and never raises an error.

        .. note::

            Depending on what this greenlet is executing and the state of the event loop,
            the exception may or may not be raised immediately when this greenlet resumes
            execution. It may be raised an a subsequent green call, or, if this greenlet
            exits before making such a call, it may not be raised at all. As of 1.1, an example
            where the exception is raised later is if this greenlet had called ``sleep(0)``; an
            example where the exception is raised immediately is if this greenlet had called ``sleep(0.1)``.

        See also :func:`gevent.kill`.

        .. versionchanged:: 0.13.0
            *block* is now ``True`` by default.
        """
        # XXX this function should not switch out if greenlet is not started but it does
        # XXX fix it (will have to override 'dead' property of greenlet.greenlet)
        if self._start_event is None:
            self._start_event = _dummy_event
        else:
            self._start_event.stop()
        if not self.dead:
            waiter = Waiter()
            self.parent.loop.run_callback(_kill, self, exception, waiter)
            if block:
                waiter.get()
                self.join(timeout)
示例#6
0
    def _gethostbyaddr(self, ip_address):
        if PY3:
            if isinstance(ip_address, str):
                ip_address = ip_address.encode("idna")
            elif not isinstance(ip_address, (bytes, bytearray)):
                raise TypeError("Expected es(idna), not %s" % type(ip_address).__name__)
        else:
            if isinstance(ip_address, text_type):
                ip_address = ip_address.encode("ascii")
            elif not isinstance(ip_address, str):
                raise TypeError("Expected string, not %s" % type(ip_address).__name__)

        waiter = Waiter(self.hub)
        try:
            self.ares.gethostbyaddr(waiter, ip_address)
            return waiter.get()
        except InvalidIP:
            result = self._getaddrinfo(ip_address, None, family=AF_UNSPEC, socktype=SOCK_DGRAM)
            if not result:
                raise
            _ip_address = result[0][-1][0]
            if isinstance(_ip_address, text_type):
                _ip_address = _ip_address.encode("ascii")
            if _ip_address == ip_address:
                raise
            waiter.clear()
            self.ares.gethostbyaddr(waiter, _ip_address)
            return waiter.get()
    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()
示例#8
0
文件: _base.py 项目: ideascf/octopus
    def _wait(self, action=None, timeout=None):
        """
        等待本service_name下的service变更
        :param timeout:
        :type timeout: float
        :return:
        """

        remain = timeout

        waiter = Waiter()
        self._oc.add_waiter(self.service_name, waiter)
        try:
            while True:
                with Timeout(remain, _TimeOut):
                    start = time.time()
                    cur_action = waiter.get()
                    remain = remain - (time.time() - start)

                    if action is None:  # 没有特别指明需要的动作
                        break
                    elif action == cur_action:  # 捕获到需要的动作
                        break
                    elif remain < 0.001:  # 剩余超时时间不足1ms
                        raise _TimeOut
                    else:
                        continue
        except _TimeOut:  # 发生超时
            return False
        except Exception as e:
            raise err.OctpParamError('catch unexpect error: %s. more: %s', e, traceback.format_exc())
        else:
            return True
        finally:
            self._oc.del_waiter(self.service_name, waiter)
示例#9
0
    def __getnameinfo(self, hostname, port, sockaddr, flags):
        result = self.__getaddrinfo(hostname,
                                    port,
                                    family=AF_UNSPEC,
                                    socktype=SOCK_DGRAM,
                                    proto=0,
                                    flags=0,
                                    fill_in_type_proto=False)
        if len(result) != 1:
            raise error('sockaddr resolved to multiple addresses')

        family, _socktype, _proto, _name, address = result[0]

        if family == AF_INET:
            if len(sockaddr) != 2:
                raise error("IPv4 sockaddr must be 2 tuple")
        elif family == AF_INET6:
            address = address[:2] + sockaddr[2:]

        waiter = Waiter(self.hub)
        self.cares.getnameinfo(waiter, address, flags)
        node, service = waiter.get()

        if service is None and PY3:
            # ares docs: "If the query did not complete
            # successfully, or one of the values was not
            # requested, node or service will be NULL ". Python 2
            # allows that for the service, but Python 3 raises
            # an error. This is tested by test_socket in py 3.4
            err = gaierror(EAI_NONAME, self.EAI_NONAME_MSG)
            err.errno = EAI_NONAME
            raise err

        return node, service or '0'
示例#10
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
示例#11
0
 def peek(self, block=True, timeout=None):
     if self.qsize():
         if self.putters:
             self._schedule_unlock()
         return self._peek()
     elif not block and get_hub() is getcurrent():
         # special case to make peek(False) runnable in the mainloop
         # greenlet there are no items in the queue; try to fix the
         # situation by unlocking putters
         while self.putters:
             putter = self.putters.pop()
             if putter:
                 putter.switch(putter)
                 if self.qsize():
                     return self._peek()
         raise Empty
     elif block:
         waiter = Waiter()
         timeout = Timeout.start_new(timeout, Empty)
         try:
             self.getters.add(waiter)
             if self.putters:
                 self._schedule_unlock()
             result = waiter.get()
             assert result is waiter, "Invalid switch into Queue.put: %r" % (result,)
             return self._peek()
         finally:
             self.getters.discard(waiter)
             timeout.cancel()
     else:
         raise Empty
示例#12
0
    def peek(self, block=True, timeout=None):
        """Return an item from the queue without removing it.

        If optional args *block* is true and *timeout* is ``None`` (the default),
        block if necessary until an item is available. If *timeout* is a positive number,
        it blocks at most *timeout* seconds and raises the :class:`Empty` exception
        if no item was available within that time. Otherwise (*block* is false), return
        an item if one is immediately available, else raise the :class:`Empty` exception
        (*timeout* is ignored in that case).
        """
        if self.qsize():
            return self._peek()
        elif self.hub is getcurrent():
            # special case to make peek(False) runnable in the mainloop greenlet
            # there are no items in the queue; try to fix the situation by unlocking putters
            while self.putters:
                self.putters.pop().put_and_switch()
                if self.qsize():
                    return self._peek()
            raise Empty
        elif block:
            waiter = Waiter()
            timeout = Timeout.start_new(timeout, Empty)
            try:
                self.getters.add(waiter)
                if self.putters:
                    self._schedule_unlock()
                result = waiter.get()
                assert result is waiter, 'Invalid switch into Queue.peek: %r' % (result, )
                return self._peek()
            finally:
                self.getters.discard(waiter)
                timeout.cancel()
        else:
            raise Empty
示例#13
0
    def _getnameinfo(self, sockaddr, flags):
        if not isinstance(flags, int):
            raise TypeError('an integer is required')
        if not isinstance(sockaddr, tuple):
            raise TypeError('getnameinfo() argument 1 must be a tuple')

        waiter = Waiter(self.hub)
        result = self._getaddrinfo(sockaddr[0],
                                   str(sockaddr[1]),
                                   family=AF_UNSPEC,
                                   socktype=SOCK_DGRAM)
        if not result:
            raise
        elif len(result) != 1:
            raise error('sockaddr resolved to multiple addresses')
        family, socktype, proto, name, address = result[0]

        if family == AF_INET:
            if len(sockaddr) != 2:
                raise error("IPv4 sockaddr must be 2 tuple")
        elif family == AF_INET6:
            address = address[:2] + sockaddr[2:]

        self.ares.getnameinfo(waiter, address, flags)
        node, service = waiter.get()
        if service is None:
            service = '0'
        return node, service
示例#14
0
    def gethostbyname_ex(self, hostname, family=AF_INET):
        if PY3:
            if isinstance(hostname, str):
                hostname = hostname.encode('idna')
            elif not isinstance(hostname, (bytes, bytearray)):
                raise TypeError('Expected es(idna), not %s' %
                                type(hostname).__name__)
        else:
            if isinstance(hostname, text_type):
                hostname = hostname.encode('ascii')
            elif not isinstance(hostname, str):
                raise TypeError('Expected string, not %s' %
                                type(hostname).__name__)

        while True:
            ares = self.ares
            try:
                waiter = Waiter(self.hub)
                ares.gethostbyname(waiter, hostname, family)
                result = waiter.get()
                if not result[-1]:
                    raise gaierror(-5, 'No address associated with hostname')
                return result
            except gaierror:
                if ares is self.ares:
                    if hostname == b'255.255.255.255':
                        # The stdlib handles this case in 2.7 and 3.x, but ares does not.
                        # It is tested by test_socket.py in 3.4.
                        # HACK: So hardcode the expected return.
                        return ('255.255.255.255', [], ['255.255.255.255'])
                    raise
示例#15
0
    def put(self, item, block=True, timeout=None):
        if self.hub is getcurrent():
            if self.getters:
                getter = self.getters.popleft()
                getter.switch(item)
                return
            raise Full

        if not block:
            timeout = 0

        waiter = Waiter()
        item = (item, waiter)
        self.putters.append(item)
        timeout = Timeout.start_new(timeout, Full)
        try:
            if self.getters:
                self._schedule_unlock()
            result = waiter.get()
            assert result is waiter, "Invalid switch into Channel.put: %r" % (
                result, )
        except:
            self._discard(item)
            raise
        finally:
            timeout.cancel()
示例#16
0
def waitany(objects, timeout=None):
    waiter = Waiter()
    switch = waiter.switch

    if not objects:
        return None

    timer = None
    if timeout is not None:
        timer = core.timer(timeout, switch, _NONE)

    try:
        for obj in objects:
            obj.rawlink(switch)

        rst = waiter.get()
        return None if rst is _NONE else rst

    finally:
        timer and timer.cancel()

        for obj in objects:
            unlink = getattr(obj, 'unlink', None)
            if unlink:
                try:
                    unlink(switch)
                except:
                    import traceback
                    traceback.print_exc()
示例#17
0
 def peek(self, block=True, timeout=None):
     if self.qsize():
         if self.putters:
             self._schedule_unlock()
         return self._peek()
     elif not block and get_hub() is getcurrent():
         # special case to make peek(False) runnable in the mainloop
         # greenlet there are no items in the queue; try to fix the
         # situation by unlocking putters
         while self.putters:
             putter = self.putters.pop()
             if putter:
                 putter.switch(putter)
                 if self.qsize():
                     return self._peek()
         raise Empty
     elif block:
         waiter = Waiter()
         timeout = Timeout.start_new(timeout, Empty)
         try:
             self.getters.add(waiter)
             if self.putters:
                 self._schedule_unlock()
             result = waiter.get()
             assert result is waiter, "Invalid switch into Queue.put: %r" % (
                 result, )
             return self._peek()
         finally:
             self.getters.discard(waiter)
             timeout.cancel()
     else:
         raise Empty
示例#18
0
    def _getnameinfo(self, sockaddr, flags):
        if not isinstance(flags, int):
            raise TypeError('an integer is required')
        if not isinstance(sockaddr, tuple):
            raise TypeError('getnameinfo() argument 1 must be a tuple')

        waiter = Waiter(self.hub)
        result = self._getaddrinfo(sockaddr[0], str(sockaddr[1]), family=AF_UNSPEC, socktype=SOCK_DGRAM)
        if not result:
            raise
        elif len(result) != 1:
            raise error('sockaddr resolved to multiple addresses')
        family, socktype, proto, name, address = result[0]

        if family == AF_INET:
            if len(sockaddr) != 2:
                raise error("IPv4 sockaddr must be 2 tuple")
        elif family == AF_INET6:
            address = address[:2] + sockaddr[2:]

        self.ares.getnameinfo(waiter, address, flags)
        node, service = waiter.get()
        if service is None:
            service = '0'
        return node, service
示例#19
0
    def gethostbyname_ex(self, hostname, family=AF_INET):
        if PY3:
            if isinstance(hostname, str):
                hostname = hostname.encode("idna")
            elif not isinstance(hostname, (bytes, bytearray)):
                raise TypeError("Expected es(idna), not %s" % type(hostname).__name__)
        else:
            if isinstance(hostname, text_type):
                hostname = hostname.encode("ascii")
            elif not isinstance(hostname, str):
                raise TypeError("Expected string, not %s" % type(hostname).__name__)

        while True:
            ares = self.ares
            try:
                waiter = Waiter(self.hub)
                ares.gethostbyname(waiter, hostname, family)
                result = waiter.get()
                if not result[-1]:
                    raise gaierror(-5, "No address associated with hostname")
                return result
            except gaierror:
                if ares is self.ares:
                    if hostname == b"255.255.255.255":
                        # The stdlib handles this case in 2.7 and 3.x, but ares does not.
                        # It is tested by test_socket.py in 3.4.
                        # HACK: So hardcode the expected return.
                        return ("255.255.255.255", [], ["255.255.255.255"])
                    raise
示例#20
0
    def peek(self, block=True, timeout=None):
        """Return an item from the queue without removing it.

        If optional args *block* is true and *timeout* is ``None`` (the default),
        block if necessary until an item is available. If *timeout* is a positive number,
        it blocks at most *timeout* seconds and raises the :class:`Empty` exception
        if no item was available within that time. Otherwise (*block* is false), return
        an item if one is immediately available, else raise the :class:`Empty` exception
        (*timeout* is ignored in that case).
        """
        if self.qsize():
            return self._peek()
        elif self.hub is getcurrent():
            # special case to make peek(False) runnable in the mainloop greenlet
            # there are no items in the queue; try to fix the situation by unlocking putters
            while self.putters:
                self.putters.pop().put_and_switch()
                if self.qsize():
                    return self._peek()
            raise Empty
        elif block:
            waiter = Waiter()
            timeout = Timeout.start_new(timeout, Empty)
            try:
                self.getters.add(waiter)
                if self.putters:
                    self._schedule_unlock()
                result = waiter.get()
                assert result is waiter, 'Invalid switch into Queue.peek: %r' % (result, )
                return self._peek()
            finally:
                self.getters.discard(waiter)
                timeout.cancel()
        else:
            raise Empty
示例#21
0
    def put(self, item, block=True, timeout=None):
        if self.hub is getcurrent():
            if self.getters:
                getter = self.getters.popleft()
                getter.switch(item)
                return
            raise Full

        if not block:
            timeout = 0

        waiter = Waiter()
        item = (item, waiter)
        self.putters.append(item)
        timeout = Timeout.start_new(timeout, Full)
        try:
            if self.getters:
                self._schedule_unlock()
            result = waiter.get()
            assert result is waiter, "Invalid switch into Channel.put: %r" % (result, )
        except:
            self._discard(item)
            raise
        finally:
            timeout.cancel()
示例#22
0
    def put(self, item, block=True, timeout=None):
        if self.hub is getcurrent():
            if self.getters:
                getter = self.getters.popleft()
                getter.switch(item)
                return
            raise Full

        if not block:
            timeout = 0

        waiter = Waiter()
        item = (item, waiter)
        self.putters.append(item)
        timeout = Timeout.start_new(timeout, Full) if timeout is not None else None
        try:
            if self.getters:
                self._schedule_unlock()
            result = waiter.get()
            if result is not waiter:
                raise InvalidSwitchError("Invalid switch into Channel.put: %r" % (result, ))
        except:
            _safe_remove(self.putters, item)
            raise
        finally:
            if timeout is not None:
                timeout.cancel()
示例#23
0
    def kill(self, exception=GreenletExit, block=True, timeout=None):
        """Raise the ``exception`` in the greenlet.

        If ``block`` is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
        If block is ``False``, the current greenlet is not unscheduled.

        The function always returns ``None`` and never raises an error.

        .. note::

            Depending on what this greenlet is executing and the state of the event loop,
            the exception may or may not be raised immediately when this greenlet resumes
            execution. It may be raised on a subsequent green call, or, if this greenlet
            exits before making such a call, it may not be raised at all. As of 1.1, an example
            where the exception is raised later is if this greenlet had called ``sleep(0)``; an
            example where the exception is raised immediately is if this greenlet had called ``sleep(0.1)``.

        See also :func:`gevent.kill`.

        .. versionchanged:: 0.13.0
            *block* is now ``True`` by default.
        .. versionchanged:: 1.1a2
            If this greenlet had never been switched to, killing it will prevent it from ever being switched to.
        """
        self.__cancel_start()

        if self.dead:
            self.__handle_death_before_start(exception)
        else:
            waiter = Waiter()
            self.parent.loop.run_callback(_kill, self, exception, waiter)
            if block:
                waiter.get()
                self.join(timeout)
示例#24
0
    def gethostbyname_ex(self, hostname, family=AF_INET):
        if PY3:
            if isinstance(hostname, str):
                hostname = hostname.encode('idna')
            elif not isinstance(hostname, (bytes, bytearray)):
                raise TypeError('Expected es(idna), not %s' %
                                type(hostname).__name__)
        else:
            if isinstance(hostname, text_type):
                hostname = hostname.encode('ascii')
            elif not isinstance(hostname, str):
                raise TypeError('Expected string, not %s' %
                                type(hostname).__name__)

        while True:
            ares = self.ares
            try:
                waiter = Waiter(self.hub)
                ares.gethostbyname(waiter, hostname, family)
                result = waiter.get()
                if not result[-1]:
                    raise gaierror(-5, 'No address associated with hostname')
                return result
            except gaierror:
                if ares is self.ares:
                    raise
示例#25
0
    def kill(self, exception=GreenletExit, block=True, timeout=None):
        """Raise the ``exception`` in the greenlet.

        If ``block`` is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
        If block is ``False``, the current greenlet is not unscheduled.

        The function always returns ``None`` and never raises an error.

        .. note::

            Depending on what this greenlet is executing and the state of the event loop,
            the exception may or may not be raised immediately when this greenlet resumes
            execution. It may be raised on a subsequent green call, or, if this greenlet
            exits before making such a call, it may not be raised at all. As of 1.1, an example
            where the exception is raised later is if this greenlet had called ``sleep(0)``; an
            example where the exception is raised immediately is if this greenlet had called ``sleep(0.1)``.

        See also :func:`gevent.kill`.

        .. versionchanged:: 0.13.0
            *block* is now ``True`` by default.
        .. versionchanged:: 1.1a2
            If this greenlet had never been switched to, killing it will prevent it from ever being switched to.
        """
        self.__cancel_start()

        if self.dead:
            self.__handle_death_before_start(exception)
        else:
            waiter = Waiter()
            self.parent.loop.run_callback(_kill, self, exception, waiter)
            if block:
                waiter.get()
                self.join(timeout)
示例#26
0
文件: queue.py 项目: BSlience/gevent
    def __get_or_peek(self, method, block, timeout):
        # Internal helper method. The `method` should be either
        # self._get when called from self.get() or self._peek when
        # called from self.peek(). Call this after the initial check
        # to see if there are items in the queue.

        if self.hub is getcurrent():
            # special case to make get_nowait() or peek_nowait() runnable in the mainloop greenlet
            # there are no items in the queue; try to fix the situation by unlocking putters
            while self.putters:
                # Note: get() used popleft(), peek used pop(); popleft
                # is almost certainly correct.
                self.putters.popleft().put_and_switch()
                if self.qsize():
                    return method()
            raise Empty()

        if not block:
            # We can't block, we're not the hub, and we have nothing
            # to return. No choice...
            raise Empty()

        waiter = Waiter()
        timeout = Timeout._start_new_or_dummy(timeout, Empty)
        try:
            self.getters.append(waiter)
            if self.putters:
                self._schedule_unlock()
            result = waiter.get()
            if result is not waiter:
                raise InvalidSwitchError('Invalid switch into Queue.get: %r' % (result, ))
            return method()
        finally:
            timeout.cancel()
            _safe_remove(self.getters, waiter)
示例#27
0
    def __get_or_peek(self, method, block, timeout):
        # Internal helper method. The `method` should be either
        # self._get when called from self.get() or self._peek when
        # called from self.peek(). Call this after the initial check
        # to see if there are items in the queue.

        if self.hub is getcurrent():
            # special case to make get_nowait() or peek_nowait() runnable in the mainloop greenlet
            # there are no items in the queue; try to fix the situation by unlocking putters
            while self.putters:
                # Note: get() used popleft(), peek used pop(); popleft
                # is almost certainly correct.
                self.putters.popleft().put_and_switch()
                if self.qsize():
                    return method()
            raise Empty()

        if not block:
            # We can't block, we're not the hub, and we have nothing
            # to return. No choice...
            raise Empty()

        waiter = Waiter()
        timeout = Timeout._start_new_or_dummy(timeout, Empty)
        try:
            self.getters.append(waiter)
            if self.putters:
                self._schedule_unlock()
            result = waiter.get()
            if result is not waiter:
                raise InvalidSwitchError('Invalid switch into Queue.get: %r' % (result, ))
            return method()
        finally:
            timeout.cancel()
            _safe_remove(self.getters, waiter)
示例#28
0
文件: queue.py 项目: BSlience/gevent
    def put(self, item, block=True, timeout=None):
        if self.hub is getcurrent():
            if self.getters:
                getter = self.getters.popleft()
                getter.switch(item)
                return
            raise Full

        if not block:
            timeout = 0

        waiter = Waiter()
        item = (item, waiter)
        self.putters.append(item)
        timeout = Timeout._start_new_or_dummy(timeout, Full)
        try:
            if self.getters:
                self._schedule_unlock()
            result = waiter.get()
            if result is not waiter:
                raise InvalidSwitchError("Invalid switch into Channel.put: %r" % (result, ))
        except:
            _safe_remove(self.putters, item)
            raise
        finally:
            timeout.cancel()
示例#29
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
示例#30
0
def resolve_reverse_ipv6(packed_ip, flags=0):
    """Lookup a PTR record for a given IPv6 address.
    To disable searching for this query, set *flags* to ``QUERY_NO_SEARCH``.
    """
    waiter = Waiter()
    core.dns_resolve_reverse_ipv6(packed_ip, flags, waiter.switch_args)
    result, _type, ttl, addrs = waiter.get()
    if result != core.DNS_ERR_NONE:
        raise DNSError(result)
    return ttl, addrs
示例#31
0
def killall(greenlets, exception=GreenletExit, block=True, polling_period=0.2):
    """Kill all the greenlets with exception (GreenletExit by default).
    Wait for them to die if block is true.
    """
    waiter = Waiter()
    core.active_event(_killall, greenlets, exception, waiter)
    if block:
        alive = waiter.wait()
        if alive:
            joinall(alive, polling_period=polling_period)
示例#32
0
def killall(greenlets, exception=GreenletExit, block=True, polling_period=0.2):
    """Kill all the greenlets with exception (GreenletExit by default).
    Wait for them to die if block is true.
    """
    waiter = Waiter()
    core.active_event(_killall, greenlets, exception, waiter)
    if block:
        alive = waiter.wait()
        if alive:
            joinall(alive, polling_period=polling_period)
示例#33
0
def kill(greenlet, exception=GreenletExit, block=True, polling_period=0.2):
    """Kill greenlet with exception (GreenletExit by default).
    Wait for it to die if block is true.
    """
    if not greenlet.dead:
        waiter = Waiter()
        core.active_event(_kill, greenlet, exception, waiter)
        if block:
            waiter.wait()
            join(greenlet, polling_period=polling_period)
示例#34
0
def kill(greenlet, exception=GreenletExit, block=True, polling_period=0.2):
    """Kill greenlet with exception (GreenletExit by default).
    Wait for it to die if block is true.
    """
    if not greenlet.dead:
        waiter = Waiter()
        core.active_event(_kill, greenlet, exception, waiter)
        if block:
            waiter.wait()
            join(greenlet, polling_period=polling_period)
示例#35
0
def resolve_reverse_ipv6(packed_ip, flags=0):
    """Lookup a PTR record for a given IPv6 address.
    To disable searching for this query, set *flags* to ``QUERY_NO_SEARCH``.
    """
    waiter = Waiter()
    core.dns_resolve_reverse_ipv6(packed_ip, flags, waiter.switch_args)
    result, _type, ttl, addrs = waiter.get()
    if result != core.DNS_ERR_NONE:
        raise DNSError(result)
    return ttl, addrs
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
示例#37
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
示例#38
0
    def getresponse(self):
        if self.resp is None:
            self.conn.make_request(self.req, self.method, self.uri)
            assert self._waiter is None, self._waiter
            self._waiter = Waiter()
            try:
                self.resp = self._waiter.get()
            finally:
                self._waiter = None

        return self.resp
示例#39
0
def resolve_ipv6(name, flags=0):
    """Lookup an AAAA record for a given *name*.
    To disable searching for this query, set *flags* to ``QUERY_NO_SEARCH``.

    Returns (ttl, list of packed IPs).
    """
    waiter = Waiter()
    core.dns_resolve_ipv6(name, flags, waiter.switch_args)
    result, _type, ttl, addrs = waiter.get()
    if result != core.DNS_ERR_NONE:
        raise DNSError(result)
    return ttl, addrs
示例#40
0
def resolve_ipv6(name, flags=0):
    """Lookup an AAAA record for a given *name*.
    To disable searching for this query, set *flags* to ``QUERY_NO_SEARCH``.

    Returns (ttl, list of packed IPs).
    """
    waiter = Waiter()
    core.dns_resolve_ipv6(name, flags, waiter.switch_args)
    result, _type, ttl, addrs = waiter.get()
    if result != core.DNS_ERR_NONE:
        raise DNSError(result)
    return ttl, addrs
示例#41
0
文件: rawconn.py 项目: snaury/copper
 def ping(self, value):
     if self._closed:
         raise self._failure
     waiter = Waiter()
     waiters = self._ping_waiters.get(value)
     if waiters is not None:
         waiters.append(waiter)
     else:
         self._ping_waiters[value] = [waiter]
     self._ping_reqs.append(value)
     self._write_ready.set()
     return waiter.get()
    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
示例#43
0
 def gethostbyname_ex(self, hostname, family=AF_INET):
     while True:
         ares = self.ares
         try:
             waiter = Waiter(self.hub)
             ares.gethostbyname(waiter, hostname, family)
             result = waiter.get()
             if not result[-1]:
                 raise gaierror(-5, 'No address associated with hostname')
             return result
         except gaierror:
             if ares is self.ares:
                 raise
示例#44
0
 def gethostbyname_ex(self, hostname, family=AF_INET):
     while True:
         ares = self.ares
         try:
             waiter = Waiter(self.hub)
             ares.gethostbyname(waiter, hostname, family)
             result = waiter.get()
             if not result[-1]:
                 raise gaierror(-5, 'No address associated with hostname')
             return result
         except gaierror:
             if ares is self.ares:
                 raise
示例#45
0
def killall(greenlets, exception=GreenletExit, block=False, timeout=None):
    if block:
        waiter = Waiter()
        core.active_event(_killall3, greenlets, exception, waiter)
        if block:
            t = Timeout.start_new(timeout)
            try:
                alive = waiter.wait()
                if alive:
                    joinall(alive, raise_error=False)
            finally:
                t.cancel()
    else:
        core.active_event(_killall, greenlets, exception)
示例#46
0
def resolve_reverse(packed_ip, flags=0):
    """Lookup a PTR record for a given IP address.
    To disable searching for this query, set *flags* to ``QUERY_NO_SEARCH``.

        >>> packed_ip = socket.inet_aton('82.94.164.162')
        >>> resolve_reverse(packed_ip)
        (10000, 'www.python.org')
    """
    waiter = Waiter()
    core.dns_resolve_reverse(packed_ip, flags, waiter.switch_args)
    result, _type, ttl, addr = waiter.get()
    if result != core.DNS_ERR_NONE:
        raise DNSError(result)
    return ttl, addr
示例#47
0
    def _getnameinfo(self, sockaddr, flags):
        if not isinstance(flags, int):
            raise TypeError('an integer is required')
        if not isinstance(sockaddr, tuple):
            raise TypeError('getnameinfo() argument 1 must be a tuple')

        address = sockaddr[0]
        if not PY3 and isinstance(address, text_type):
            address = address.encode('ascii')

        if not isinstance(address, string_types):
            raise TypeError('sockaddr[0] must be a string, not %s' %
                            type(address).__name__)

        port = sockaddr[1]
        if not isinstance(port, int):
            raise TypeError('port must be an integer, not %s' % type(port))

        waiter = Waiter(self.hub)
        result = self._getaddrinfo(address,
                                   str(sockaddr[1]),
                                   family=AF_UNSPEC,
                                   socktype=SOCK_DGRAM)
        if not result:
            reraise(*sys.exc_info())
        elif len(result) != 1:
            raise error('sockaddr resolved to multiple addresses')
        family, _socktype, _proto, _name, address = result[0]

        if family == AF_INET:
            if len(sockaddr) != 2:
                raise error("IPv4 sockaddr must be 2 tuple")
        elif family == AF_INET6:
            address = address[:2] + sockaddr[2:]

        self.ares.getnameinfo(waiter, address, flags)
        node, service = waiter.get()

        if service is None:
            if PY3:
                # ares docs: "If the query did not complete
                # successfully, or one of the values was not
                # requested, node or service will be NULL ". Python 2
                # allows that for the service, but Python 3 raises
                # an error. This is tested by test_socket in py 3.4
                err = gaierror('nodename nor servname provided, or not known')
                err.errno = 8
                raise err
            service = '0'
        return node, service
示例#48
0
    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
示例#49
0
def resolve_reverse(packed_ip, flags=0):
    """Lookup a PTR record for a given IP address.
    To disable searching for this query, set *flags* to ``QUERY_NO_SEARCH``.

        >>> packed_ip = socket.inet_aton('82.94.164.162')
        >>> resolve_reverse(packed_ip)
        (10000, 'www.python.org')
    """
    waiter = Waiter()
    core.dns_resolve_reverse(packed_ip, flags, waiter.switch_args)
    result, _type, ttl, addr = waiter.get()
    if result != core.DNS_ERR_NONE:
        raise DNSError(result)
    return ttl, addr
示例#50
0
    def kill(self, exception=GreenletExit, block=False, timeout=None):
        """Raise the exception in the greenlet.

        If block is ``False`` (the default), the current greenlet is not unscheduled.
        If block is ``True``, wait until the greenlet dies or the optional timeout expires.

        Return ``None``.
        """
        if not self.dead:
            waiter = Waiter()
            core.active_event(_kill, self, exception, waiter)
            if block:
                waiter.wait()
                self.join(timeout)
示例#51
0
 def call_method(self, *args, **kwargs):
     """Call a method."""
     callback = kwargs.get('callback')
     if callback is not None:
         super(GEventDBusConnection, self).call_method(*args, **kwargs)
         return
     waiter = Waiter()
     def _gevent_callback(message):
         waiter.switch(message)
     kwargs['callback'] = _gevent_callback
     super(GEventDBusConnection, self).call_method(*args, **kwargs)
     reply = waiter.get()
     self._handle_errors(reply)
     return reply
示例#52
0
    def kill(self, exception=GreenletExit, block=True, timeout=None):
        """
        Raise the ``exception`` in the greenlet.

        If ``block`` is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
        If block is ``False``, the current greenlet is not unscheduled.

        The function always returns ``None`` and never raises an error.

        .. note::

            Depending on what this greenlet is executing and the state
            of the event loop, the exception may or may not be raised
            immediately when this greenlet resumes execution. It may
            be raised on a subsequent green call, or, if this greenlet
            exits before making such a call, it may not be raised at
            all. As of 1.1, an example where the exception is raised
            later is if this greenlet had called :func:`sleep(0)
            <gevent.sleep>`; an example where the exception is raised
            immediately is if this greenlet had called
            :func:`sleep(0.1) <gevent.sleep>`.

        .. caution::

            Use care when killing greenlets. If the code executing is not
            exception safe (e.g., makes proper use of ``finally``) then an
            unexpected exception could result in corrupted state.

        See also :func:`gevent.kill`.

        :keyword type exception: The type of exception to raise in the greenlet. The default
            is :class:`GreenletExit`, which indicates a :meth:`successful` completion
            of the greenlet.

        .. versionchanged:: 0.13.0
            *block* is now ``True`` by default.
        .. versionchanged:: 1.1a2
            If this greenlet had never been switched to, killing it will prevent it from ever being switched to.
        """
        self.__cancel_start()

        if self.dead:
            self.__handle_death_before_start(exception)
        else:
            waiter = Waiter() if block else None
            self.parent.loop.run_callback(_kill, self, exception, waiter)
            if block:
                waiter.get()
                self.join(timeout)
示例#53
0
文件: greenlet.py 项目: hokhyk/gevent
    def kill(self, exception=GreenletExit, block=True, timeout=None):
        """
        Raise the ``exception`` in the greenlet.

        If ``block`` is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
        If block is ``False``, the current greenlet is not unscheduled.

        The function always returns ``None`` and never raises an error.

        .. note::

            Depending on what this greenlet is executing and the state
            of the event loop, the exception may or may not be raised
            immediately when this greenlet resumes execution. It may
            be raised on a subsequent green call, or, if this greenlet
            exits before making such a call, it may not be raised at
            all. As of 1.1, an example where the exception is raised
            later is if this greenlet had called :func:`sleep(0)
            <gevent.sleep>`; an example where the exception is raised
            immediately is if this greenlet had called
            :func:`sleep(0.1) <gevent.sleep>`.

        .. caution::

            Use care when killing greenlets. If the code executing is not
            exception safe (e.g., makes proper use of ``finally``) then an
            unexpected exception could result in corrupted state.

        See also :func:`gevent.kill`.

        :keyword type exception: The type of exception to raise in the greenlet. The default
            is :class:`GreenletExit`, which indicates a :meth:`successful` completion
            of the greenlet.

        .. versionchanged:: 0.13.0
            *block* is now ``True`` by default.
        .. versionchanged:: 1.1a2
            If this greenlet had never been switched to, killing it will prevent it from ever being switched to.
        """
        self.__cancel_start()

        if self.dead:
            self.__handle_death_before_start(exception)
        else:
            waiter = Waiter() if block else None
            self.parent.loop.run_callback(_kill, self, exception, waiter)
            if block:
                waiter.get()
                self.join(timeout)
示例#54
0
 def _gethostbyaddr(self, ip_address):
     waiter = Waiter(self.hub)
     try:
         self.ares.gethostbyaddr(waiter, ip_address)
         return waiter.get()
     except InvalidIP:
         result = self._getaddrinfo(ip_address, None, family=AF_UNSPEC, socktype=SOCK_DGRAM)
         if not result:
             raise
         _ip_address = result[0][-1][0]
         if _ip_address == ip_address:
             raise
         waiter.clear()
         self.ares.gethostbyaddr(waiter, _ip_address)
         return waiter.get()
示例#55
0
 def call_method(self, *args, **kwargs):
     """Call a method."""
     callback = kwargs.get('callback')
     if callback is not None:
         super(GEventDBusConnection, self).call_method(*args, **kwargs)
         return
     waiter = Waiter()
     def _gevent_callback(message):
         waiter.switch(message)
     kwargs['callback'] = _gevent_callback
     super(GEventDBusConnection, self).call_method(*args, **kwargs)
     reply = waiter.get()
     if reply.get_type() == _tdbus.DBUS_MESSAGE_TYPE_ERROR:
         raise DBusError(reply.get_error_name())
     return reply
示例#56
0
class TestWaiter(greentest.GenericWaitTestCase):
    def setUp(self):
        super(TestWaiter, self).setUp()
        self.waiter = Waiter()

    def wait(self, timeout):
        evt = core.timer(timeout, self.waiter.switch, None)
        try:
            return self.waiter.get()
        finally:
            evt.cancel()

    def test(self):
        waiter = self.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()
示例#57
0
def killall(greenlets, exception=GreenletExit, block=True, timeout=None):
    if not greenlets:
        return
    loop = greenlets[0].loop
    if block:
        waiter = Waiter()
        loop.run_callback(_killall3, greenlets, exception, waiter)
        t = Timeout.start_new(timeout)
        try:
            alive = waiter.get()
            if alive:
                joinall(alive, raise_error=False)
        finally:
            t.cancel()
    else:
        loop.run_callback(_killall, greenlets, exception)