Exemple #1
0
    def wait(self):
        """Wait until another coroutine calls send.
        Returns the value the other coroutine passed to
        send.

        >>> from eventlet import coros, api
        >>> evt = coros.event()
        >>> def wait_on():
        ...    retval = evt.wait()
        ...    print "waited for", retval
        >>> _ = api.spawn(wait_on)
        >>> evt.send('result')
        >>> api.sleep(0)
        waited for result

        Returns immediately if the event has already
        occured.

        >>> evt.wait()
        'result'
        """
        if self._result is NOT_USED:
            self._waiters.add(api.getcurrent())
            try:
                return api.get_hub().switch()
            finally:
                self._waiters.discard(api.getcurrent())
        if self._exc is not None:
            api.getcurrent().throw(*self._exc)
        return self._result
Exemple #2
0
 def switch(self):
     assert api.getcurrent() is not self.greenlet, "Cannot switch from MAINLOOP to MAINLOOP"
     try:
        api.getcurrent().parent = self.greenlet
     except ValueError:
        pass
     return self.greenlet.switch()
Exemple #3
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)
Exemple #4
0
 def acquire(self, blocking=True):
     if not blocking and self.locked():
         return False
     if self.counter <= 0:
         self._waiters.add(api.getcurrent())
         try:
             while self.counter <= 0:
                 api.get_hub().switch()
         finally:
             self._waiters.discard(api.getcurrent())
     self.counter -= 1
     return True
Exemple #5
0
 def link_exception(self, listener=None, link=None):
     if self.value is not _NOT_USED and self._exc is None:
         return
     if listener is None:
         listener = api.getcurrent()
     if link is None:
         link = self.getLink(listener)
     if self.ready() and listener is api.getcurrent():
         link(self)
     else:
         self._exception_links[listener] = link
         if self.value is not _NOT_USED:
             self._start_send_exception()
     return link
Exemple #6
0
 def link_exception(self, listener=None, link=None):
     if self.value is not _NOT_USED and self._exc is None:
         return
     if listener is None:
         listener = api.getcurrent()
     if link is None:
         link = self.getLink(listener)
     if self.ready() and listener is api.getcurrent():
         link(self)
     else:
         self._exception_links[listener] = link
         if self.value is not _NOT_USED:
             self._start_send_exception()
     return link
Exemple #7
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(failure):
        if cur:
            if getcurrent() is cur[0]:
                synchronous.append((None, failure))
            else:
                failure.throwExceptionIntoGenerator(cur[0])

    deferred.addCallbacks(cb, eb)
    if synchronous:
        result, failure = synchronous[0]
        if failure is not None:
            failure.raiseException()
        return result
    try:
        return get_hub().switch()
    finally:
        del cur[0]
Exemple #8
0
 def switch(self):
     cur = api.getcurrent()
     assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'
     switch_out = getattr(cur, 'switch_out', None)
     if switch_out is not None:
         try:
             switch_out()
         except:
             traceback.print_exception(*sys.exc_info())
     if self.greenlet.dead:
         self.greenlet = api.Greenlet(self.run)
     try:
         api.getcurrent().parent = self.greenlet
     except ValueError:
         pass
     return self.greenlet.switch()
Exemple #9
0
 def send(self, value):
     """Wake up the greenlet that is calling wait() currently (if there is one).
     Can only be called from get_hub().greenlet.
     """
     assert api.getcurrent() is hubs.get_hub().greenlet
     if self.greenlet is not None:
         self.greenlet.switch(value)
Exemple #10
0
 def send_exception(self, *throw_args):
     """Make greenlet calling wait() wake up (if there is a wait()).
     Can only be called from get_hub().greenlet.
     """
     assert api.getcurrent() is hubs.get_hub().greenlet
     if self.greenlet is not None:
         self.greenlet.throw(*throw_args)
Exemple #11
0
 def send(self, value):
     """Wake up the greenlet that is calling wait() currently (if there is one).
     Can only be called from get_hub().greenlet.
     """
     assert api.getcurrent() is hubs.get_hub().greenlet
     if self.greenlet is not None:
         self.greenlet.switch(value)
Exemple #12
0
 def send_exception(self, *throw_args):
     """Make greenlet calling wait() wake up (if there is a wait()).
     Can only be called from get_hub().greenlet.
     """
     assert api.getcurrent() is hubs.get_hub().greenlet
     if self.greenlet is not None:
         self.greenlet.throw(*throw_args)
Exemple #13
0
 def cb(value):
     if cur:
         if getcurrent() is cur[0]:
             synchronous.append((value, None))
         else:
             cur[0].switch(value)
     return value
Exemple #14
0
    def execute(self, func, *args, **kwargs):
        """Execute func in one of the coroutines maintained
        by the pool, when one is free.

        Immediately returns a Proc object which can be queried
        for the func's result.

        >>> pool = Pool()
        >>> task = pool.execute(lambda a: ('foo', a), 1)
        >>> task.wait()
        ('foo', 1)
        """
        # if reentering an empty pool, don't try to wait on a coroutine freeing
        # itself -- instead, just execute in the current coroutine
        if self.sem.locked() and api.getcurrent() in self.procs:
            p = proc.spawn(func, *args, **kwargs)
            try:
                p.wait()
            except:
                pass
        else:
            self.sem.acquire()
            p = self.procs.spawn(func, *args, **kwargs)
            # assuming the above line cannot raise
            p.link(lambda p: self.sem.release())
        if self.results is not None:
            p.link(self.results)
        return p
Exemple #15
0
    def execute(self, func, *args, **kwargs):
        """Execute func in one of the coroutines maintained
        by the pool, when one is free.

        Immediately returns a :class:`~eventlet.proc.Proc` object which can be
        queried for the func's result.

        >>> pool = Pool()
        >>> task = pool.execute(lambda a: ('foo', a), 1)
        >>> task.wait()
        ('foo', 1)
        """
        # if reentering an empty pool, don't try to wait on a coroutine freeing
        # itself -- instead, just execute in the current coroutine
        if self.sem.locked() and api.getcurrent() in self.procs:
            p = proc.spawn(func, *args, **kwargs)
            try:
                p.wait()
            except:
                pass
        else:
            self.sem.acquire()
            p = self.procs.spawn(func, *args, **kwargs)
            # assuming the above line cannot raise
            p.link(lambda p: self.sem.release())
        if self.results is not None:
            p.link(self.results)
        return p
Exemple #16
0
 def schedule_call_local(self, seconds, cb, *args, **kwargs):
     current = api.getcurrent()
     if current is self.greenlet:
         return self.schedule_call_global(seconds, cb, *args, **kwargs)
     event_impl = event.event(_scheduled_call_local, (cb, args, kwargs, current))
     wrapper = event_wrapper(event_impl, seconds=seconds)
     self.events_to_add.append(wrapper)
     return wrapper
Exemple #17
0
    def wait(self, timeout=None, *throw_args):
        """Wait until :meth:`send` or :meth:`send_exception` is called or
        *timeout* has expired. Return the argument of :meth:`send` or raise the
        argument of :meth:`send_exception`. If *timeout* has expired, ``None``
        is returned.

        The arguments, when provided, specify how many seconds to wait and what
        to do when *timeout* has expired. They are treated the same way as
        :func:`~eventlet.api.timeout` treats them.
        """
        if self.value is not _NOT_USED:
            if self._exc is None:
                return self.value
            else:
                api.getcurrent().throw(*self._exc)
        if timeout is not None:
            timer = api.timeout(timeout, *throw_args)
            timer.__enter__()
            if timeout == 0:
                if timer.__exit__(None, None, None):
                    return
                else:
                    try:
                        api.getcurrent().throw(*timer.throw_args)
                    except:
                        if not timer.__exit__(*sys.exc_info()):
                            raise
                    return
            EXC = True
        try:
            try:
                waiter = Waiter()
                self.link(waiter)
                try:
                    return waiter.wait()
                finally:
                    self.unlink(waiter)
            except:
                EXC = False
                if timeout is None or not timer.__exit__(*sys.exc_info()):
                    raise
        finally:
            if timeout is not None and EXC:
                timer.__exit__(None, None, None)
Exemple #18
0
    def wait(self, timeout=None, *throw_args):
        """Wait until :meth:`send` or :meth:`send_exception` is called or
        *timeout* has expired. Return the argument of :meth:`send` or raise the
        argument of :meth:`send_exception`. If *timeout* has expired, ``None``
        is returned.

        The arguments, when provided, specify how many seconds to wait and what
        to do when *timeout* has expired. They are treated the same way as
        :func:`~eventlet.api.timeout` treats them.
        """
        if self.value is not _NOT_USED:
            if self._exc is None:
                return self.value
            else:
                api.getcurrent().throw(*self._exc)
        if timeout is not None:
            timer = api.timeout(timeout, *throw_args)
            timer.__enter__()
            if timeout==0:
                if timer.__exit__(None, None, None):
                    return
                else:
                    try:
                        api.getcurrent().throw(*timer.throw_args)
                    except:
                        if not timer.__exit__(*sys.exc_info()):
                            raise
                    return
            EXC = True
        try:
            try:
                waiter = Waiter()
                self.link(waiter)
                try:
                    return waiter.wait()
                finally:
                    self.unlink(waiter)
            except:
                EXC = False
                if timeout is None or not timer.__exit__(*sys.exc_info()):
                    raise
        finally:
            if timeout is not None and EXC:
                timer.__exit__(None, None, None)
Exemple #19
0
def killall(procs, *throw_args, **kwargs):
    if not throw_args:
        throw_args = (ProcExit, )
    wait = kwargs.pop('wait', False)
    if kwargs:
        raise TypeError('Invalid keyword argument for proc.killall(): %s' % ', '.join(kwargs.keys()))
    for g in procs:
        if not g.dead:
            hubs.get_hub().schedule_call_global(0, g.throw, *throw_args)
    if wait and api.getcurrent() is not hubs.get_hub().greenlet:
        api.sleep(0)
Exemple #20
0
def killall(procs, *throw_args, **kwargs):
    if not throw_args:
        throw_args = (ProcExit, )
    wait = kwargs.pop('wait', False)
    if kwargs:
        raise TypeError('Invalid keyword argument for proc.killall(): %s' %
                        ', '.join(kwargs.keys()))
    for g in procs:
        if not g.dead:
            hubs.get_hub().schedule_call_global(0, g.throw, *throw_args)
    if wait and api.getcurrent() is not hubs.get_hub().greenlet:
        api.sleep(0)
Exemple #21
0
 def wait(self):
     """Wait until send or send_exception is called. Return value passed
     into send() or raise exception passed into send_exception().
     """
     assert self.greenlet is None
     current = api.getcurrent()
     assert current is not hubs.get_hub().greenlet
     self.greenlet = current
     try:
         return hubs.get_hub().switch()
     finally:
         self.greenlet = None
Exemple #22
0
 def send(self, result=None, exc=None):
     if exc is not None and not isinstance(exc, tuple):
         exc = (exc, )
     if api.getcurrent() is api.get_hub().greenlet:
         self.items.append((result, exc))
         if self._waiters:
             api.get_hub().schedule_call_global(0, self._do_switch)
     else:
         if self._waiters and self._senders:
             api.sleep(0)
         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:
             api.get_hub().schedule_call_global(0, self._do_switch)
         if len(self.items) > self.max_size:
             self._senders.add(api.getcurrent())
             try:
                 api.get_hub().switch()
             finally:
                 self._senders.discard(api.getcurrent())
Exemple #23
0
 def wait(self):
     """Wait until send or send_exception is called. Return value passed
     into send() or raise exception passed into send_exception().
     """
     assert self.greenlet is None
     current = api.getcurrent()
     assert current is not hubs.get_hub().greenlet
     self.greenlet = current
     try:
         return hubs.get_hub().switch()
     finally:
         self.greenlet = None
Exemple #24
0
    def kill(self, *throw_args):
        """
        Raise an exception in the greenlet. Unschedule the current greenlet so
        that this :class:`Proc` can handle the exception (or die).

        The exception can be specified with *throw_args*. By default,
        :class:`ProcExit` is raised.
        """
        if not self.dead:
            if not throw_args:
                throw_args = (ProcExit, )
            hubs.get_hub().schedule_call_global(0, self.greenlet.throw, *throw_args)
            if api.getcurrent() is not hubs.get_hub().greenlet:
                api.sleep(0)
Exemple #25
0
 def run(self):
     while True:
         try:
             self.dispatch()
         except api.GreenletExit:
             break
         except self.SYSTEM_EXCEPTIONS:
             raise
         except:
             if self.signal_exc_info is not None:
                 self.schedule_call_global(0, api.getcurrent().parent.throw, *self.signal_exc_info)
                 self.signal_exc_info = None
             else:
                 traceback.print_exc()
Exemple #26
0
    def kill(self, *throw_args):
        """
        Raise an exception in the greenlet. Unschedule the current greenlet so
        that this :class:`Proc` can handle the exception (or die).

        The exception can be specified with *throw_args*. By default,
        :class:`ProcExit` is raised.
        """
        if not self.dead:
            if not throw_args:
                throw_args = (ProcExit, )
            hubs.get_hub().schedule_call_global(0, self.greenlet.throw,
                                                *throw_args)
            if api.getcurrent() is not hubs.get_hub().greenlet:
                api.sleep(0)
Exemple #27
0
    def start(self):
        notification_center = NotificationCenter()

        if self.greenlet is not None:
            return
        self.greenlet = api.getcurrent()

        current_address = host.default_ip
        while True:
            new_address = host.default_ip
            # make sure the address stabilized
            api.sleep(5)
            if new_address != host.default_ip:
                continue
            if new_address != current_address:
                notification_center.post_notification(name='SystemIPAddressDidChange', sender=self, data=TimestampedNotificationData(old_ip_address=current_address, new_ip_address=new_address))
                current_address = new_address
            api.sleep(5)
def main():
    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) != 5:
        print "Usage: %s controller_pid httpd_fd death_fd factory_qual factory_args" % (
            sys.argv[0], )
        sys.exit(1)

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

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

    ## Set up the reloader
    if options.reload:
        watch = config.get('watch', None)
        if watch:
            watching = ' and %s' % watch
        else:
            watching = ''
        print "(%s) reloader watching sys.modules%s" % (os.getpid(), watching)
        api.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)
    api.spawn(read_pipe_and_die, int(death_fd), api.getcurrent())

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

    serve_from_child(
        sock, config, controller_pid)
Exemple #29
0
 def wait(self):
     if self.items:
         result, exc = self.items.popleft()
         if exc is None:
             return result
         else:
             api.getcurrent().throw(*exc)
     else:
         self._waiters.add(api.getcurrent())
         try:
             result, exc = api.get_hub().switch()
             if exc is None:
                 return result
             else:
                 api.getcurrent().throw(*exc)
         finally:
             self._waiters.discard(api.getcurrent())
Exemple #30
0
    def start(self):
        notification_center = NotificationCenter()

        if self.greenlet is not None:
            return
        self.greenlet = api.getcurrent()

        current_address = host.default_ip
        while True:
            new_address = host.default_ip
            # make sure the address stabilized
            api.sleep(5)
            if new_address != host.default_ip:
                continue
            if new_address != current_address:
                notification_center.post_notification(
                    name='SystemIPAddressDidChange',
                    sender=self,
                    data=TimestampedNotificationData(
                        old_ip_address=current_address,
                        new_ip_address=new_address))
                current_address = new_address
            api.sleep(5)
Exemple #31
0
 def wait(self):
     if self.items:
         result, exc = self.items.popleft()
         if len(self.items) <= self.max_size:
             api.get_hub().schedule_call_global(0, self._do_switch)
         if exc is None:
             return result
         else:
             api.getcurrent().throw(*exc)
     else:
         if self._senders:
             api.get_hub().schedule_call_global(0, self._do_switch)
         self._waiters.add(api.getcurrent())
         try:
             result, exc = api.get_hub().switch()
             if exc is None:
                 return result
             else:
                 api.getcurrent().throw(*exc)
         finally:
             self._waiters.discard(api.getcurrent())
Exemple #32
0
def get_ident():
    return id(api.getcurrent())
Exemple #33
0
 def __init__(self, *args, **kwargs):
     self.greenlet = getcurrent()
     Timer.__init__(self, *args, **kwargs)
Exemple #34
0
 def unlink(self, listener=None):
     if listener is None:
         listener = api.getcurrent()
     self._value_links.pop(listener, None)
     self._exception_links.pop(listener, None)
Exemple #35
0
 def unlink(self, listener=None):
     if listener is None:
         listener = api.getcurrent()
     self._value_links.pop(listener, None)
     self._exception_links.pop(listener, None)
def main():
    if not sys.argv[1:] or sys.argv[1] not in ["client", "server"] or sys.argv[3:]:
        sys.exit(__doc__)

    role = sys.argv[1]

    if sys.argv[2:]:
        filename = sys.argv[2]
    else:
        filename = None

    if role == "client":
        local_uri = URI(session_id="client", use_tls=False)
        remote_uri = URI(session_id="server", use_tls=False)
        connector = ConnectorDirect(logger=Logger(is_enabled_func=lambda: False))
        dest = None
    else:
        local_uri = URI(session_id="server", use_tls=False)
        remote_uri = URI(session_id="client", use_tls=False)
        connector = AcceptorDirect(logger=Logger(is_enabled_func=lambda: False))
        if filename:
            if os.path.exists(filename) and os.path.isfile(filename):
                sys.exit("%s already exists. Remove it first or provide another destination" % filename)
            dest = file(filename, "w+")

    connector.prepare(local_uri)
    transport = connector.complete([remote_uri])

    main_greenlet = api.getcurrent()

    def on_received(chunk=None, error=None):
        if chunk is not None:
            if chunk.content_type == "text/plain":
                print "\nreceived message: %s" % chunk.data
            elif chunk.content_type == "application/octet-stream":
                fro, to, total = chunk.byte_range
                dest.seek(fro - 1)
                dest.write(chunk.data)
                if total:
                    percent = " (%d%%)" % (100.0 * (fro - 1 + len(chunk.data)) / total)
                else:
                    percent = ""
                speed = (fro - 1 + len(chunk.data)) / float((time() - start_time)) / 1024.0 / 1024
                print "\rwrote %s bytes to %s. %s bytes total%s %.2f MB/s       " % (
                    len(chunk.data),
                    filename,
                    fro - 1 + len(chunk.data),
                    percent,
                    speed,
                ),
                if chunk.contflag == "$":
                    api.spawn(api.kill, main_greenlet, proc.ProcExit)
        if error is not None:
            api.spawn(api.kill, main_greenlet, error.type, error.value, error.tb)

    session = MSRPSession(transport, on_incoming_cb=on_received)

    def sender():
        while True:
            session.send_message("hello from %s" % role, "text/plain")
            api.sleep(3)

    sender = proc.spawn_link_exception(proc.wrap_errors(proc.ProcExit, sender))

    if filename and role == "client":
        if os.path.isfile(filename):
            size = os.stat(filename).st_size
        else:
            size = None
        f = file(filename)
        outgoing_file = OutgoingFile(f, size, "application/octet-stream")
        print "Sending %s %s bytes" % (filename, size)
        session.send_file(outgoing_file)
    start_time = time()

    try:
        api.get_hub().switch()  # sleep forever
    except (proc.ProcExit, ConnectionDone):
        pass
    finally:
        sender.kill()
        session.shutdown()
Exemple #37
0
 def eb(failure):
     if cur:
         if getcurrent() is cur[0]:
             synchronous.append((None, failure))
         else:
             failure.throwExceptionIntoGenerator(cur[0])
Exemple #38
0
 def __init__(self, *args, **kwargs):
     self.greenlet = api.getcurrent()
     DelayedCall.__init__(self, *args, **kwargs)