Exemplo n.º 1
0
    def call(self, method, message=None, timeout=None):
        """Send a message to the Actor this object addresses.
        Wait for a result. If a timeout in seconds is passed, raise
        eventlet.TimeoutError if no result is returned in less than the timeout.
        
        This could have nicer syntax somehow to make it look like an actual method call.
        """
        message_id = str(uuid.uuid1())
        my_address = eventlet.getcurrent().address
        self.cast(
                {'call': message_id, 'method': method,
                'address': my_address, 'message': message})
        if timeout is None:
            cancel = None
        else:
            ## Raise any TimeoutError to the caller so they can handle it
            cancel = eventlet.Timeout(timeout, eventlet.TimeoutError)

        RSP = {'response': message_id, 'message': object}
        EXC = {'response': message_id, 'exception': object}
        INV = {'response': message_id, 'invalid_method': str}

        pattern, response = eventlet.getcurrent().receive(RSP, EXC, INV)

        if cancel is not None:
            cancel.cancel()

        if pattern is INV:
            raise RemoteAttributeError(method)
        elif pattern is EXC:
            raise RemoteException(response)
        return response['message']
Exemplo n.º 2
0
 def switch(self):
     assert getcurrent() is not self.greenlet, \
            "Cannot switch from MAINLOOP to MAINLOOP"
     try:
         getcurrent().parent = self.greenlet
     except ValueError:
         pass
     return self.greenlet.switch()
Exemplo n.º 3
0
 def switch(self):
     assert getcurrent() is not self.greenlet, \
            "Cannot switch from MAINLOOP to MAINLOOP"
     try:
        getcurrent().parent = self.greenlet
     except ValueError:
        pass
     return self.greenlet.switch()
Exemplo n.º 4
0
    def switch(self):
        assert eventlet.getcurrent() is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'

        try:
            eventlet.getcurrent().parent = self.greenlet
        except ValueError:
            pass

        return self.greenlet.switch()
Exemplo n.º 5
0
    def switch(self):
        assert eventlet.getcurrent() is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'

        try:
            eventlet.getcurrent().parent = self.greenlet
        except ValueError:
            pass

        return self.greenlet.switch()
Exemplo n.º 6
0
 def wait(self):
     """The difference from Queue.wait: if there is an only item in the
     Queue and it is an exception, raise it, but keep it in the Queue, so
     that future calls to wait() will raise it again.
     """
     if self.has_error() and len(self.items) == 1:
         # the last item, which is an exception, raise without emptying the Queue
         getcurrent().throw(*self.items[0][1])
     else:
         return Queue.wait(self)
Exemplo n.º 7
0
 def wait(self):
     """The difference from Queue.wait: if there is an only item in the
     Queue and it is an exception, raise it, but keep it in the Queue, so
     that future calls to wait() will raise it again.
     """
     if self.has_error() and len(self.items)==1:
         # the last item, which is an exception, raise without emptying the Queue
         getcurrent().throw(*self.items[0][1])
     else:
         return Queue.wait(self)
Exemplo n.º 8
0
def select(read_list, write_list, error_list, timeout=None):
    # error checking like this is required by the stdlib unit tests
    if timeout is not None:
        try:
            timeout = float(timeout)
        except ValueError:
            raise TypeError("Expected number for timeout")
    hub = get_hub()
    timers = []
    current = eventlet.getcurrent()
    assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
    ds = {}
    for r in read_list:
        ds[get_fileno(r)] = {'read': r}
    for w in write_list:
        ds.setdefault(get_fileno(w), {})['write'] = w
    for e in error_list:
        ds.setdefault(get_fileno(e), {})['error'] = e

    listeners = []

    def on_read(d):
        original = ds[get_fileno(d)]['read']
        current.switch(([original], [], []))

    def on_write(d):
        original = ds[get_fileno(d)]['write']
        current.switch(([], [original], []))

    def on_timeout2():
        current.switch(([], [], []))

    def on_timeout():
        # ensure that BaseHub.run() has a chance to call self.wait()
        # at least once before timed out.  otherwise the following code
        # can time out erroneously.
        #
        # s1, s2 = socket.socketpair()
        # print(select.select([], [s1], [], 0))
        timers.append(hub.schedule_call_global(0, on_timeout2))

    if timeout is not None:
        timers.append(hub.schedule_call_global(timeout, on_timeout))
    try:
        for k, v in six.iteritems(ds):
            if v.get('read'):
                listeners.append(
                    hub.add(hub.READ, k, on_read, current.throw, lambda: None))
            if v.get('write'):
                listeners.append(
                    hub.add(hub.WRITE, k, on_write, current.throw,
                            lambda: None))
        try:
            return hub.switch()
        finally:
            for l in listeners:
                hub.remove(l)
    finally:
        for t in timers:
            t.cancel()
Exemplo n.º 9
0
 def run(self, *args, **kwargs):
     greenlet_id = id(eventlet.getcurrent())
     _actor_map[greenlet_id] = self
     try:
         self._callback(*args, **kwargs)
     finally:
         del _actor_map[greenlet_id]
Exemplo n.º 10
0
	def handle_conn(self):
		print('connected by', self.addr)
		self.recv_greenlet = eventlet.getcurrent()
		self.send_greenlet = eventlet.spawn(self.handle_send_queue)
		self.last_recv_time = datetime.utcnow()
		while True:
			try:
				data = self.conn.recv(4096)
			except OSError as e:
				if e.errno in [errno.EBADF, errno.ECONNRESET]:
					self.disconnect()
					break
				raise
			if not data:
				self.disconnect()
				break
			if self.last_buf is not None:
				data = self.last_buf + data
				self.last_buf = None
			lines = data.split(b'\r\n')
			for i in range(len(lines) - 1):
				line = str(lines[i], 'utf-8', 'replace')
				if DEBUG:
					print('<-', line)
				message = ClientMessage(line)
				self.handle_message(message)
			last = lines[-1]
			if last:
				self.last_buf = last
Exemplo n.º 11
0
    def gwait(self, timeout=None):
        """Wait from an eventlet

        This cooperatively blocks the current eventlet by switching to
        the hub.  The hub will switch back to this eventlet when it
        gets notified.

        Usually you can just call .wait() which will dispatch to this
        method if you are in an eventlet.

        Returns True if this thread/eventlet was notified and False
        when a timeout occurred.
        """
        waiter = eventlet.getcurrent()
        hub = eventlet.hubs.get_hub()
        self._create_pipe(hub)
        self._waiters.add((waiter, hub))
        if timeout and timeout > 0:
            timeout = eventlet.Timeout(timeout)
            try:
                with timeout:
                    hub.switch()
            except eventlet.Timeout, t:
                if t is not timeout:
                    raise
                self._waiters.discard((waiter, hub))
                return False
            else:
                return True
Exemplo n.º 12
0
    def close(self):
        with self.lock:
            if self.is_closed:
                return
            self.is_closed = True

        log.debug("Closing connection (%s) to %s" % (id(self), self.host))

        cur_gthread = eventlet.getcurrent()

        if self._read_watcher and self._read_watcher != cur_gthread:
            self._read_watcher.kill()
        if self._write_watcher and self._write_watcher != cur_gthread:
            self._write_watcher.kill()
        if self._socket:
            self._socket.close()
        log.debug("Closed socket to %s" % (self.host,))

        if not self.is_defunct:
            self.error_all_callbacks(
                cassandra_connection.ConnectionShutdown(
                    "Connection to %s was closed" % self.host
                )
            )
            # don't leave in-progress operations hanging
            self.connected_event.set()
Exemplo n.º 13
0
 def __get_item_when_available(self, method, block=True, timeout=None):
     if self.qsize():
         if self.putters:
             self._schedule_unlock()
         return method()
     elif not block and get_hub().greenlet is eventlet.getcurrent():
         while self.putters:
             putter = self.putters.pop()
             if putter:
                 putter.switch(putter)
                 if self.qsize():
                     return method()
     elif block:
         waiter = Waiter()
         timeout = eventlet.Timeout(timeout, Empty)
         try:
             self.getters.add(waiter)
             if self.putters:
                 self._schedule_unlock()
             result = waiter.wait()
             assert result is waiter, 'Invalid switch into Queue.get: %r' % (result,)
             return method()
         finally:
             self.getters.discard(waiter)
             timeout.cancel()
     else:
         raise Empty
Exemplo n.º 14
0
 def wrapper():
     assert getcurrent() is get_hub().greenlet
     try:
         result = func(*args, **kwargs)
         done.send(result)
     except Exception as e:
         done.send_exception(e)
Exemplo n.º 15
0
    def spawn(self, function, *args, **kwargs):
        """Run the *function* with its arguments in its own green thread.
        Returns the :class:`GreenThread <eventlet.GreenThread>`
        object that is running the function, which can be used to retrieve the
        results.

        If the pool is currently at capacity, ``spawn`` will block until one of
        the running greenthreads completes its task and frees up a slot.

        This function is reentrant; *function* can call ``spawn`` on the same
        pool without risk of deadlocking the whole thing.
        """
        # if reentering an empty pool, don't try to wait on a coroutine freeing
        # itself -- instead, just execute in the current coroutine
        current = eventlet.getcurrent()
        if self.sem.locked() and current in self.coroutines_running:
            # a bit hacky to use the GT without switching to it
            gt = eventlet.greenthread.GreenThread(current)
            gt.main(function, args, kwargs)
            return gt
        else:
            self.sem.acquire()
            gt = eventlet.spawn(function, *args, **kwargs)
            if not self.coroutines_running:
                self.no_coros_running = eventlet.Event()
            self.coroutines_running.add(gt)
            gt.link(self._spawn_done)
        return gt
Exemplo n.º 16
0
def block_on(deferred):
    cur = [getcurrent()]
    synchronous = []
    def cb(value):
        if cur:
            if getcurrent() is cur[0]:
                synchronous.append((value, None))
            else:
                cur[0].switch(value)
        return value
    def eb(fail):
        if cur:
            if getcurrent() is cur[0]:
                synchronous.append((None, fail))
            else:
                fail.throwExceptionIntoGenerator(cur[0])
    deferred.addCallbacks(cb, eb)
    if synchronous:
        result, fail = synchronous[0]
        if fail is not None:
            fail.raiseException()
        return result
    try:
        return get_hub().switch()
    finally:
        del cur[0]
Exemplo n.º 17
0
 def cb(value):
     if cur:
         if getcurrent() is cur[0]:
             synchronous.append((value, None))
         else:
             cur[0].switch(value)
     return value
Exemplo n.º 18
0
 def test_raise(self):
     p = self.p = proc.spawn(
         lambda: getcurrent().throw(ExpectedError('test_raise')))
     self._test_raise(p, True, proc.LinkedFailed)
     # repeating the same with dead process
     for _ in range(3):
         self._test_raise(p, False, proc.LinkedFailed)
Exemplo n.º 19
0
    def test_multiple_listeners_error(self):
        # if there was an error while calling a callback
        # it should not prevent the other listeners from being called
        # also, all of the errors should be logged, check the output
        # manually that they are
        p = proc.spawn(lambda: 5)
        results = []

        def listener1(*args):
            results.append(10)
            raise ExpectedError('listener1')

        def listener2(*args):
            results.append(20)
            raise ExpectedError('listener2')

        def listener3(*args):
            raise ExpectedError('listener3')

        p.link(listener1)
        p.link(listener2)
        p.link(listener3)
        sleep(DELAY * 10)
        assert results in [[10, 20], [20, 10]], results

        p = proc.spawn(lambda: getcurrent().throw(
            ExpectedError('test_multiple_listeners_error')))
        results = []
        p.link(listener1)
        p.link(listener2)
        p.link(listener3)
        sleep(DELAY * 10)
        assert results in [[10, 20], [20, 10]], results
Exemplo n.º 20
0
 def cb(value):
     if cur:
         if getcurrent() is cur[0]:
             synchronous.append((value, None))
         else:
             cur[0].switch(value)
     return value
Exemplo n.º 21
0
    def test_multiple_listeners_error(self):
        # if there was an error while calling a callback
        # it should not prevent the other listeners from being called
        # also, all of the errors should be logged, check the output
        # manually that they are
        p = proc.spawn(lambda : 5)
        results = []
        def listener1(*args):
            results.append(10)
            raise ExpectedError('listener1')
        def listener2(*args):
            results.append(20)
            raise ExpectedError('listener2')
        def listener3(*args):
            raise ExpectedError('listener3')
        p.link(listener1)
        p.link(listener2)
        p.link(listener3)
        sleep(DELAY*10)
        assert results in [[10, 20], [20, 10]], results

        p = proc.spawn(lambda : getcurrent().throw(ExpectedError('test_multiple_listeners_error')))
        results = []
        p.link(listener1)
        p.link(listener2)
        p.link(listener3)
        sleep(DELAY*10)
        assert results in [[10, 20], [20, 10]], results
Exemplo n.º 22
0
def block_on(deferred):
    cur = [getcurrent()]
    synchronous = []

    def cb(value):
        if cur:
            if getcurrent() is cur[0]:
                synchronous.append((value, None))
            else:
                cur[0].switch(value)
        return value

    def eb(fail):
        if cur:
            if getcurrent() is cur[0]:
                synchronous.append((None, fail))
            else:
                fail.throwExceptionIntoGenerator(cur[0])

    deferred.addCallbacks(cb, eb)
    if synchronous:
        result, fail = synchronous[0]
        if fail is not None:
            fail.raiseException()
        return result
    try:
        return get_hub().switch()
    finally:
        del cur[0]
Exemplo n.º 23
0
 def waitall(self):
     """Waits until all greenthreads in the pool are finished working."""
     assert eventlet.getcurrent() not in self.coroutines_running, \
         "Calling waitall() from within one of the " \
         "GreenPool's greenthreads will never terminate."
     if self.running():
         self.no_coros_running.wait()
Exemplo n.º 24
0
def spawn_link(spawnable, *args, **kw):
    """Just like spawn, but call actor.add_link(eventlet.getcurrent().address)
    before returning the newly-created actor.

    The currently running Actor will be linked to the new actor. If an
    exception occurs or the Actor finishes execution, a message will
    be sent to the Actor which called spawn_link with details.

    When an exception occurs, the message will have a pattern like:

        {'address': eventlet.actor.Address, 'exception': dict}

    The "exception" dict will have information from the stack trace extracted
    into a tree of simple Python objects.

    On a normal return from the Actor, the actor's return value is given
    in a message like:

        {'address': eventlet.actor.Address, 'exit': object}
    """
    if is_actor_type(spawnable):
        spawnable = spawnable()
    else:
        spawnable = Actor(spawnable)

    spawnable._args = (args, kw)
    spawnable.add_link(eventlet.getcurrent().address)
    eventlet.spawn_after(0, spawnable.switch)
    return spawnable.address
Exemplo n.º 25
0
def create_process(cmd, run_as_root=False, addl_env=None,
                   tpool_proxy=True):
    cmd = list(map(str, cmd))

    LOG.debug("Running command: %s", cmd)
    env = os.environ.copy()
    if addl_env:
        env.update(addl_env)

    popen = subprocess.Popen
    obj = popen(cmd, shell=False,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                env=env,
                preexec_fn=None,
                close_fds=False)
    if tpool_proxy and eventlet.getcurrent().parent:
        # If we intend to access the process streams, we need to wrap this
        # in a tpool proxy object, avoding blocking other greenthreads.
        #
        # The 'file' type is not available on Python 3.x.
        file_type = getattr(builtins, 'file', io.IOBase)
        obj = tpool.Proxy(obj, autowrap=(file_type, ))

    return obj, cmd
Exemplo n.º 26
0
 def wrapper():
     assert getcurrent() is get_hub().greenlet
     try:
         result = func(*args, **kwargs)
         done.send(result)
     except Exception as e:
         done.send_exception(e)
Exemplo n.º 27
0
 def waitall(self):
     """Waits until all greenthreads in the pool are finished working."""
     assert eventlet.getcurrent() not in self.coroutines_running, \
         "Calling waitall() from within one of the " \
         "GreenPool's greenthreads will never terminate."
     if self.running():
         self.no_coros_running.wait()
Exemplo n.º 28
0
    def spawn(self, function, *args, **kwargs):
        """Run the *function* with its arguments in its own green thread.
        Returns the :class:`GreenThread <eventlet.GreenThread>`
        object that is running the function, which can be used to retrieve the
        results.

        If the pool is currently at capacity, ``spawn`` will block until one of
        the running greenthreads completes its task and frees up a slot.

        This function is reentrant; *function* can call ``spawn`` on the same
        pool without risk of deadlocking the whole thing.
        """
        # if reentering an empty pool, don't try to wait on a coroutine freeing
        # itself -- instead, just execute in the current coroutine
        current = eventlet.getcurrent()
        if self.sem.locked() and current in self.coroutines_running:
            # a bit hacky to use the GT without switching to it
            gt = eventlet.greenthread.GreenThread(current)
            gt.main(function, args, kwargs)
            return gt
        else:
            self.sem.acquire()
            gt = eventlet.spawn(function, *args, **kwargs)
            if not self.coroutines_running:
                self.no_coros_running = eventlet.Event()
            self.coroutines_running.add(gt)
            gt.link(self._spawn_done)
        return gt
Exemplo n.º 29
0
Arquivo: actor.py Projeto: tlvu/mochi
 def run(self, *args, **kwargs):
     greenlet_id = id(eventlet.getcurrent())
     _actor_map[greenlet_id] = self
     try:
         self._callback(*args, **kwargs)
     finally:
         del _actor_map[greenlet_id]
Exemplo n.º 30
0
def create_process(cmd, run_as_root=False, addl_env=None,
                   tpool_proxy=True):
    cmd = list(map(str, cmd))

    LOG.debug("Running command: %s", cmd)
    env = os.environ.copy()
    if addl_env:
        env.update(addl_env)

    popen = subprocess.Popen
    obj = popen(cmd, shell=False,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                env=env,
                preexec_fn=None,
                close_fds=False)
    if tpool_proxy and eventlet.getcurrent().parent:
        # If we intend to access the process streams, we need to wrap this
        # in a tpool proxy object, avoding blocking other greenthreads.
        #
        # The 'file' type is not available on Python 3.x.
        file_type = getattr(six.moves.builtins, 'file', io.IOBase)
        obj = tpool.Proxy(obj, autowrap=(file_type, ))

    return obj, cmd
Exemplo n.º 31
0
 def func():
     try:
         gt = eventlet.getcurrent()
         fut = aioeventlet.wrap_greenthread(gt)
     except Exception as exc:
         event.send_exception(exc)
     else:
         event.send(fut)
Exemplo n.º 32
0
 def _get_sender_test_case_id():
     current = eventlet.getcurrent()
     # NOTE(gibi) not all eventlet spawn is under our control, so there can
     # be senders without test_case_id set, find the first ancestor that
     # was spawned from nova.utils.spawn[_n] and therefore has the id set.
     while not getattr(current, 'test_case_id', None):
         current = current.parent
     return current.test_case_id
Exemplo n.º 33
0
def select(read_list, write_list, error_list, timeout=None):
    # error checking like this is required by the stdlib unit tests
    if timeout is not None:
        try:
            timeout = float(timeout)
        except ValueError:
            raise TypeError("Expected number for timeout")
    hub = get_hub()
    timers = []
    current = eventlet.getcurrent()
    assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
    ds = {}
    for r in read_list:
        ds[get_fileno(r)] = {'read': r}
    for w in write_list:
        ds.setdefault(get_fileno(w), {})['write'] = w
    for e in error_list:
        ds.setdefault(get_fileno(e), {})['error'] = e

    listeners = []

    def on_read(d):
        original = ds[get_fileno(d)]['read']
        current.switch(([original], [], []))

    def on_write(d):
        original = ds[get_fileno(d)]['write']
        current.switch(([], [original], []))

    def on_timeout2():
        current.switch(([], [], []))

    def on_timeout():
        # ensure that BaseHub.run() has a chance to call self.wait()
        # at least once before timed out.  otherwise the following code
        # can time out erroneously.
        #
        # s1, s2 = socket.socketpair()
        # print(select.select([], [s1], [], 0))
        timers.append(hub.schedule_call_global(0, on_timeout2))

    if timeout is not None:
        timers.append(hub.schedule_call_global(timeout, on_timeout))
    try:
        for k, v in six.iteritems(ds):
            if v.get('read'):
                listeners.append(hub.add(hub.READ, k, on_read, current.throw, lambda: None))
            if v.get('write'):
                listeners.append(hub.add(hub.WRITE, k, on_write, current.throw, lambda: None))
        try:
            return hub.switch()
        finally:
            for l in listeners:
                hub.remove(l)
    finally:
        for t in timers:
            t.cancel()
Exemplo n.º 34
0
 def send(self, result=None, exc=None):
     if exc is not None and not isinstance(exc, tuple):
         exc = (exc, )
     if eventlet.getcurrent() is hubs.get_hub().greenlet:
         self.items.append((result, exc))
         if self._waiters:
             hubs.get_hub().schedule_call_global(0, self._do_switch)
     else:
         self.items.append((result, exc))
         # note that send() does not work well with timeouts. if your timeout fires
         # after this point, the item will remain in the queue
         if self._waiters:
             hubs.get_hub().schedule_call_global(0, self._do_switch)
         if len(self.items) > self.max_size:
             self._senders.add(eventlet.getcurrent())
             try:
                 hubs.get_hub().switch()
             finally:
                 self._senders.discard(eventlet.getcurrent())
Exemplo n.º 35
0
            def __init__(self, *args, **kwargs):
                # Tell the test which thread won the race
                _runner[0] = eventlet.getcurrent()
                running_event.set()

                start_event.wait()
                super(SteppingFakeExecutor, self).__init__(*args, **kwargs)
                done_event.set()

                finish_event.wait()
Exemplo n.º 36
0
            def start(self):
                # Tell the test which thread won the race
                runner[0] = eventlet.getcurrent()
                running_event.set()

                start_event.wait()
                super(SteppingFakeExecutor, self).start()
                done_event.set()

                finish_event.wait()
Exemplo n.º 37
0
 def wait(self):
     """Wait until switch() or throw() is called.
     """
     assert self.greenlet is None, 'This Waiter is already used by %r' % (
         self.greenlet, )
     self.greenlet = eventlet.getcurrent()
     try:
         return active_hub.inst.switch()
     finally:
         self.greenlet = None
Exemplo n.º 38
0
Arquivo: utils.py Projeto: ahmb/nameko
def fail_fast_imap(pool, call, items):
    """ Run a function against each item in a given list, yielding each
    function result in turn, where the function call is handled in a
    :class:`~eventlet.greenthread.GreenThread` spawned by the provided pool.

    If any function raises an exception, all other ongoing threads are killed,
    and the exception is raised to the caller.

    This function is similar to :meth:`~eventlet.greenpool.GreenPool.imap`.

    :param pool: Pool to spawn function threads from
    :type pool: eventlet.greenpool.GreenPool
    :param call: Function call to make, expecting to receive an item from the
        given list
    """
    result_queue = LightQueue(maxsize=len(items))
    spawned_threads = set()

    def handle_result(finished_thread):
        try:
            thread_result = finished_thread.wait()
            spawned_threads.remove(finished_thread)
            result_queue.put((thread_result, None))
        except Exception:
            spawned_threads.remove(finished_thread)
            result_queue.put((None, sys.exc_info()))

    for item in items:
        gt = pool.spawn(call, item)
        spawned_threads.add(gt)
        gt.link(handle_result)

    while spawned_threads:
        result, exc_info = result_queue.get()
        if exc_info is not None:
            # Kill all other ongoing threads
            for ongoing_thread in spawned_threads:
                ongoing_thread.kill()
            # simply raising here (even raising a full exc_info) isn't
            # sufficient to preserve the original stack trace.
            # greenlet.throw() achieves this.
            eventlet.getcurrent().throw(*exc_info)
        yield result
Exemplo n.º 39
0
 def send(self, result=None, exc=None):
     if exc is not None and not isinstance(exc, tuple):
         exc = (exc, )
     if eventlet.getcurrent() is hubs.get_hub().greenlet:
         self.items.append((result, exc))
         if self._waiters:
             hubs.get_hub().schedule_call_global(0, self._do_switch)
     else:
         self.items.append((result, exc))
         # note that send() does not work well with timeouts. if your timeout fires
         # after this point, the item will remain in the queue
         if self._waiters:
             hubs.get_hub().schedule_call_global(0, self._do_switch)
         if len(self.items) > self.max_size:
             self._senders.add(eventlet.getcurrent())
             try:
                 hubs.get_hub().switch()
             finally:
                 self._senders.discard(eventlet.getcurrent())
Exemplo n.º 40
0
def fail_fast_imap(pool, call, items):
    """ Run a function against each item in a given list, yielding each
    function result in turn, where the function call is handled in a
    :class:`~eventlet.greenthread.GreenThread` spawned by the provided pool.

    If any function raises an exception, all other ongoing threads are killed,
    and the exception is raised to the caller.

    This function is similar to :meth:`~eventlet.greenpool.GreenPool.imap`.

    :param pool: Pool to spawn function threads from
    :type pool: eventlet.greenpool.GreenPool
    :param call: Function call to make, expecting to receive an item from the
        given list
    """
    result_queue = LightQueue(maxsize=len(items))
    spawned_threads = set()

    def handle_result(finished_thread):
        try:
            thread_result = finished_thread.wait()
            spawned_threads.remove(finished_thread)
            result_queue.put((thread_result, None))
        except Exception:
            spawned_threads.remove(finished_thread)
            result_queue.put((None, sys.exc_info()))

    for item in items:
        gt = pool.spawn(call, item)
        spawned_threads.add(gt)
        gt.link(handle_result)

    while spawned_threads:
        result, exc_info = result_queue.get()
        if exc_info is not None:
            # Kill all other ongoing threads
            for ongoing_thread in spawned_threads:
                ongoing_thread.kill()
            # simply raising here (even raising a full exc_info) isn't
            # sufficient to preserve the original stack trace.
            # greenlet.throw() achieves this.
            eventlet.getcurrent().throw(*exc_info)
        yield result
Exemplo n.º 41
0
            def __init__(self, *args, **kwargs):
                # Tell the test which thread won the race
                _runner[0] = eventlet.getcurrent()
                running_event.set()

                start_event.wait()
                super(SteppingFakeExecutor, self).__init__(*args, **kwargs)
                done_event.set()

                finish_event.wait()
Exemplo n.º 42
0
            def start(self):
                # Tell the test which thread won the race
                runner[0] = eventlet.getcurrent()
                running_event.set()

                start_event.wait()
                super(SteppingFakeExecutor, self).start()
                done_event.set()

                finish_event.wait()
Exemplo n.º 43
0
 def throw(self, *throw_args):
     """Make greenlet calling wait() wake up (if there is a wait()).
     Can only be called from Hub's greenlet.
     """
     assert eventlet.getcurrent() is active_hub.inst.greenlet, \
         "Can only use Waiter.switch method from the mainloop"
     if self.greenlet is not None:
         try:
             self.greenlet.throw(*throw_args)
         except Exception:
             traceback.print_exc()
Exemplo n.º 44
0
 def switch(self, value=None):
     """Wake up the greenlet that is calling wait() currently (if there is one).
     Can only be called from Hub's greenlet.
     """
     assert eventlet.getcurrent() is active_hub.inst.greenlet, \
         "Can only use Waiter.switch method from the mainloop"
     if self.greenlet is not None:
         try:
             self.greenlet.switch(value)
         except Exception:
             traceback.print_exc()
Exemplo n.º 45
0
 def wait(self):
     if self.value is PENDING:
         if self.thread not in (None, eventlet.getcurrent()):
             self.thread.wait()
     for ch in self.children:
         ch.wait()
     if self.child_errors > 0 and self.value is not ERROR:
         errors = [e for e in self.leaf_errors if not e._recovered]
         if errors:
             self.value = ERROR
             self.exception = (ChildError, ChildError(self, self.leaf_errors), None)
Exemplo n.º 46
0
 def test_wait_all_exception_order(self):
     # if there're several exceptions raised, the earliest one must be raised by wait
     def first():
         sleep(0.1)
         raise ExpectedError('first')
     a = proc.spawn(first)
     b = proc.spawn(lambda : getcurrent().throw(ExpectedError('second')))
     try:
         proc.waitall([a, b])
     except ExpectedError, ex:
         assert 'second' in str(ex), repr(str(ex))
Exemplo n.º 47
0
    def on_stopping(self):
        """

        """
        #Ensure we're not a member of worker pool we're flushing.
        if getcurrent() in self.workers:
            return spawn(self.on_stopping).join()

        try:
            self.workers.flush(self.worker_stop_timeout)
        except ScatterTimeout:
            self.log.warning('Failed to stop all workers after {0} seconds.'.format(self.worker_stop_timeout))
Exemplo n.º 48
0
def avoid_blocking_call(f, *args, **kwargs):
    """Ensures that the invoked method will not block other greenthreads.

    Performs the call in a different thread using tpool.execute when called
    from a greenthread.
    """
    # Note that eventlet.getcurrent will always return a greenlet object.
    # In case of a greenthread, the parent greenlet will always be the hub
    # loop greenlet.
    if eventlet.getcurrent().parent:
        return tpool.execute(f, *args, **kwargs)
    else:
        return f(*args, **kwargs)
Exemplo n.º 49
0
def main():
    log.debug('here')
    parser = optparse.OptionParser()
    parser.add_option("-r", "--reload",
        action='store_true', dest='reload',
        help='If --reload is passed, reload the server any time '
        'a loaded module changes.')

    options, args = parser.parse_args()

    if len(args) != 6:
        print "Usage: %s controller_pid httpd_fd death_fd warn_fd factory_qual factory_args" % (
            sys.argv[0], )
        sys.exit(1)

    controller_pid, httpd_fd, death_fd, warn_fd, factory_qual, factory_args = args
    controller_pid = int(controller_pid)
    config = spawning.util.named(factory_qual)(json.loads(factory_args))

    setproctitle("spawn: child (%s)" % ", ".join(config.get("args")))

    log.debug('httpd_fd (%s), death_fd (%s), warn_fd(%s)', httpd_fd, death_fd, warn_fd)
    
    ## Set up status reporter, if requested
    init_statusobj(config.get('status_port'))

    ## Set up the reloader
    if config.get('reload'):
        watch = config.get('watch', None)
        if watch:
            watching = ' and %s' % watch
        else:
            watching = ''
        print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching)
        eventlet.spawn(
            reloader_dev.watch_forever, controller_pid, 1, watch)

    ## The parent will catch sigint and tell us to shut down
    #signal.signal(signal.SIGINT, signal.SIG_IGN)
    ## Expect a SIGHUP when we want the child to die
    #signal.signal(signal.SIGHUP, child_sighup)
    eventlet.spawn(read_pipe_and_die, get_fd(death_fd, os.O_RDONLY), eventlet.getcurrent())

    ## Make the socket object from the fd given to us by the controller
    sock = eventlet.greenio.GreenSocket(
        socket.fromfd(int(httpd_fd), socket.AF_INET, socket.SOCK_STREAM))

    serve_from_child(
        sock, config, controller_pid, get_fd(warn_fd, os.O_WRONLY))
Exemplo n.º 50
0
def callMethodInEventLoop(func, *args, **kwargs):
    if not get_hub().running or getcurrent() is get_hub().greenlet:
        return func(*args, **kwargs)

    done = Event()
    def wrapper():
        assert getcurrent() is get_hub().greenlet
        try:
            result = func(*args, **kwargs)
            done.send(result)
        except Exception as e:
            done.send_exception(e)
    clear_sys_exc_info()
    QTimer.singleShot(0, wrapper)
    return done.wait()
Exemplo n.º 51
0
 def main(self,local_addr,message_id,method,message,timeout):
     my_address = eventlet.getcurrent().address
     local_addr | {'call':message_id,
                   'method':method,
                   'address':my_address,
                   'message':message}
     if timeout is None:
         cancel = None
     else:
         cancel = eventlet.Timeout(timeout,eventlet.TimeoutError)
     RSP = {'response':message_id,'message':object}
     EXC = {'response':message_id,'exception':object}
     INV = {'response':message_id,'invalid_method':str}
     _,res = self.receive(RSP,EXC,INV)
     return res
Exemplo n.º 52
0
 def test_wait_error(self):
     def x():
         sleep(DELAY)
         return 1
     x = proc.spawn(x)
     z = proc.spawn(lambda : 3)
     y = proc.spawn(lambda : getcurrent().throw(ExpectedError('test_wait_error')))
     y.link(x)
     x.link(y)
     y.link(z)
     z.link(y)
     self.assertRaises(ExpectedError, proc.waitall, [x, y, z])
     self.assertRaises(proc.LinkedFailed, proc.waitall, [x])
     self.assertEqual(proc.waitall([z]), [3])
     self.assertRaises(ExpectedError, proc.waitall, [y])
Exemplo n.º 53
0
	def disconnect(self):
		print('disconnecting', self.addr)
		current_greenlet = eventlet.getcurrent()
		for greenlet in [self.recv_greenlet, self.send_greenlet]:
			# we might be called by handle_conn/quit, handle_send_queue, or ping_all/disconnect_all
			if greenlet is not current_greenlet:
				greenlet.kill()

		for channel in self.channels:
			channel.quit(self)
		self.conn.close()
		try:
			del users[self.nick]
		except KeyError:
			pass
Exemplo n.º 54
0
 def _spawn_n_impl(self, func, args, kwargs, coro):
     try:
         try:
             func(*args, **kwargs)
         except (KeyboardInterrupt, SystemExit, greenlet.GreenletExit):
             raise
         except:
             if DEBUG:
                 traceback.print_exc()
     finally:
         if coro is None:
             return
         else:
             coro = eventlet.getcurrent()
             self._spawn_done(coro)
Exemplo n.º 55
0
 def _fetch_current_thread_functor():
     # Until https://github.com/eventlet/eventlet/issues/172 is resolved
     # or addressed we have to use complicated workaround to get a object
     # that will not be recycled; the usage of threading.current_thread()
     # doesn't appear to currently be monkey patched and therefore isn't
     # reliable to use (and breaks badly when used as all threads share
     # the same current_thread() object)...
     try:
         import eventlet
         from eventlet import patcher
         green_threaded = patcher.is_monkey_patched('thread')
     except ImportError:
         green_threaded = False
     if green_threaded:
         return lambda: eventlet.getcurrent()
     else:
         return lambda: threading.current_thread()
Exemplo n.º 56
0
def avoid_blocking_call(f, *args, **kwargs):
    """Ensure that the method "f" will not block other greenthreads.

    Performs the call to the function "f" received as parameter in a
    different thread using tpool.execute when called from a greenthread.
    This will ensure that the function "f" will not block other greenthreads.
    If not called from a greenthread, it will invoke the function "f" directly.
    The function "f" will receive as parameters the arguments "args" and
    keyword arguments "kwargs".
    """
    # Note that eventlet.getcurrent will always return a greenlet object.
    # In case of a greenthread, the parent greenlet will always be the hub
    # loop greenlet.
    if eventlet.getcurrent().parent:
        return tpool.execute(f, *args, **kwargs)
    else:
        return f(*args, **kwargs)