Пример #1
0
    def test_multiple_waiters(self):
        # tests that multiple waiters get their results back
        q = coros.queue()

        def waiter(q, evt):
            evt.send(q.wait())

        sendings = ['1', '2', '3', '4']
        evts = [coros.event() for x in sendings]
        for i, x in enumerate(sendings):
            api.spawn(waiter, q, evts[i])

        api.sleep(0.01)  # get 'em all waiting

        results = set()

        def collect_pending_results():
            for i, e in enumerate(evts):
                timer = api.exc_after(0.001, api.TimeoutError)
                try:
                    x = e.wait()
                    results.add(x)
                    timer.cancel()
                except api.TimeoutError:
                    pass  # no pending result at that event
            return len(results)

        q.send(sendings[0])
        self.assertEqual(collect_pending_results(), 1)
        q.send(sendings[1])
        self.assertEqual(collect_pending_results(), 2)
        q.send(sendings[2])
        q.send(sendings[3])
        self.assertEqual(collect_pending_results(), 4)
Пример #2
0
    def fan(self, block, input_list):
        queue = coros.queue(0)
        results = []
        exceptional_results = 0
        for index, input_item in enumerate(input_list):
            pool_item = self.get()

            ## Fan out
            api.spawn(
                self._invoke, block, pool_item, input_item, index, queue)

        ## Fan back in
        for i in range(len(input_list)):
            ## Wait for all guys to send to the queue
            index, value = queue.wait()
            if isinstance(value, Exception):
                exceptional_results += 1
            results.append((index, value))

        results.sort()
        results = [value for index, value in results]

        if exceptional_results:
            if exceptional_results == len(results):
                raise AllFailed(results)
            raise SomeFailed(results)
        return results
Пример #3
0
    def fan(self, block, input_list):
        queue = coros.queue(0)
        results = []
        exceptional_results = 0
        for index, input_item in enumerate(input_list):
            pool_item = self.get()

            ## Fan out
            api.spawn(self._invoke, block, pool_item, input_item, index, queue)

        ## Fan back in
        for i in range(len(input_list)):
            ## Wait for all guys to send to the queue
            index, value = queue.wait()
            if isinstance(value, Exception):
                exceptional_results += 1
            results.append((index, value))

        results.sort()
        results = [value for index, value in results]

        if exceptional_results:
            if exceptional_results == len(results):
                raise AllFailed(results)
            raise SomeFailed(results)
        return results
Пример #4
0
    def test_reset(self):
        evt = coros.event()

        # calling reset before send should throw
        self.assertRaises(AssertionError, evt.reset)

        value = 'some stuff'

        def send_to_event():
            evt.send(value)

        api.spawn(send_to_event)
        self.assertEqual(evt.wait(), value)

        # now try it again, and we should get the same exact value,
        # and we shouldn't be allowed to resend without resetting
        value2 = 'second stuff'
        self.assertRaises(AssertionError, evt.send, value2)
        self.assertEqual(evt.wait(), value)

        # reset and everything should be happy
        evt.reset()

        def send_to_event2():
            evt.send(value2)

        api.spawn(send_to_event2)
        self.assertEqual(evt.wait(), value2)
Пример #5
0
    def test_timeout_and_final_write(self):
        # This test verifies that a write on a socket that we've
        # stopped listening for doesn't result in an incorrect switch
        rpipe, wpipe = os.pipe()
        rfile = os.fdopen(rpipe,"rb",1)
        wrap_rfile = greenio.GreenPipe(rfile)
        wfile = os.fdopen(wpipe,"wb",1)
        wrap_wfile = greenio.GreenPipe(wfile)

        def sender(evt):
            api.sleep(0.02)
            wrap_wfile.write('hi')
            evt.send('sent via event')

        from eventlib import coros
        evt = coros.event()
        api.spawn(sender, evt)
        try:
            # try and get some data off of this pipe
            # but bail before any is sent
            api.exc_after(0.01, api.TimeoutError)
            _c = wrap_rfile.read(1)
            self.fail()
        except api.TimeoutError:
            pass

        result = evt.wait()
        self.assertEqual(result, 'sent via event')
Пример #6
0
    def test_waiters_get_woken(self):
        # verify that when there's someone waiting on an empty pool
        # and someone puts an immediately-closed connection back in
        # the pool that the waiter gets woken
        self.pool = self.create_pool(max_size=1, max_age=0)

        conn = self.pool.get()
        self.assertEqual(self.pool.free(), 0)
        self.assertEqual(self.pool.waiting(), 0)
        e = coros.event()

        def retrieve(pool, ev):
            c = pool.get()
            ev.send(c)

        api.spawn(retrieve, self.pool, e)
        api.sleep(0)  # these two sleeps should advance the retrieve
        api.sleep(0)  # coroutine until it's waiting in get()
        self.assertEqual(self.pool.free(), 0)
        self.assertEqual(self.pool.waiting(), 1)
        self.pool.put(conn)
        timer = api.exc_after(0.3, api.TimeoutError)
        conn = e.wait()
        timer.cancel()
        self.assertEqual(self.pool.free(), 0)
        self.assertEqual(self.pool.waiting(), 0)
Пример #7
0
def setup():
    global _threads
    for i in range(0,_nthreads):
        _threads[i] = threading.Thread(target=tworker)
        _threads[i].setDaemon(True)
        _threads[i].start()

    api.spawn(tpool_trampoline)
Пример #8
0
    def test_spawn_is_not_cancelled(self):
        def func():
            spawn(self.lst.pop)
            # exiting immediatelly, but self.lst.pop must be called

        spawn(func)
        sleep(0.1)
        assert self.lst == [], self.lst
Пример #9
0
    def test_timer_cancelled_upon_greenlet_exit(self):
        def func():
            call_after(0.1, self.lst.pop)

        spawn(func)
        assert self.lst == [1], self.lst
        sleep(0.2)
        assert self.lst == [1], self.lst
Пример #10
0
def setup():
    global _threads
    for i in range(0, _nthreads):
        _threads[i] = threading.Thread(target=tworker)
        _threads[i].setDaemon(True)
        _threads[i].start()

    api.spawn(tpool_trampoline)
Пример #11
0
    def test_senders_that_die(self):
        q = coros.queue()

        def do_send(q):
            q.send('sent')

        api.spawn(do_send, q)
        self.assertEqual(q.wait(), 'sent')
Пример #12
0
    def test_waiting_for_event(self):
        evt = coros.event()
        value = 'some stuff'

        def send_to_event():
            evt.send(value)

        api.spawn(send_to_event)
        self.assertEqual(evt.wait(), value)
Пример #13
0
    def test_timer_fired(self):
        def func():
            call_after(0.1, self.lst.pop)
            sleep(0.2)

        spawn(func)
        assert self.lst == [1], self.lst
        sleep(0.3)
        assert self.lst == [], self.lst
Пример #14
0
    def test_send_last(self):
        q = coros.queue()

        def waiter(q):
            timer = api.exc_after(0.1, api.TimeoutError)
            self.assertEqual(q.wait(), 'hi2')
            timer.cancel()

        api.spawn(waiter, q)
        api.sleep(0)
        api.sleep(0)
        q.send('hi2')
Пример #15
0
    def test_send(self):
        event1 = event()
        event2 = event()

        spawn(event1.send, 'hello event1')
        exc_after(0, ValueError('interrupted'))
        try:
            result = event1.wait()
        except ValueError:
            X = object()
            result = with_timeout(DELAY, event2.wait, timeout_value=X)
            assert result is X, 'Nobody sent anything to event2 yet it received %r' % (
                result, )
Пример #16
0
 def test_bounded(self):
     # this was originally semaphore's doctest
     sem = coros.BoundedSemaphore(2, limit=3)
     self.assertEqual(sem.acquire(), True)
     self.assertEqual(sem.acquire(), True)
     api.spawn(sem.release)
     self.assertEqual(sem.acquire(), True)
     self.assertEqual(-3, sem.balance)
     sem.release()
     sem.release()
     sem.release()
     api.spawn(sem.acquire)
     sem.release()
     self.assertEqual(3, sem.balance)
Пример #17
0
    def test_waiting(self):
        def do_wait(q, evt):
            result = q.wait()
            evt.send(result)

        q = coros.queue()
        e1 = coros.event()
        api.spawn(do_wait, q, e1)
        api.sleep(0)
        self.assertEqual(1, waiting(q))
        q.send('hi')
        api.sleep(0)
        self.assertEqual(0, waiting(q))
        self.assertEqual('hi', e1.wait())
        self.assertEqual(0, waiting(q))
Пример #18
0
    def test_013_empty_return(self):
        from eventlib import httpc

        def wsgi_app(environ, start_response):
            start_response("200 OK", [])
            return [""]

        certificate_file = os.path.join(os.path.dirname(__file__),
                                        'test_server.crt')
        private_key_file = os.path.join(os.path.dirname(__file__),
                                        'test_server.key')
        sock = api.ssl_listener(('', 4202), certificate_file, private_key_file)
        api.spawn(wsgi.server, sock, wsgi_app)

        res = httpc.get("https://localhost:4202/foo")
        self.assertEqual(res, '')
Пример #19
0
 def setUp(self):
     self.logfile = StringIO()
     self.victim = api.spawn(wsgi.server,
                             api.tcp_listener(('0.0.0.0', 31337)),
                             self.site_class(),
                             log=self.logfile,
                             max_size=128)
Пример #20
0
    def test_blocks_on_pool(self):
        waiter = coros.queue(0)

        def greedy():
            self.pool.get()
            self.pool.get()
            self.pool.get()
            self.pool.get()
            # No one should be waiting yet.
            self.assertEquals(self.pool.waiting(), 0)
            # The call to the next get will unschedule this routine.
            self.pool.get()
            # So this send should never be called.
            waiter.send('Failed!')

        killable = api.spawn(greedy)

        # no one should be waiting yet.
        self.assertEquals(self.pool.waiting(), 0)

        ## Wait for greedy
        api.sleep(0)

        ## Greedy should be blocking on the last get
        self.assertEquals(self.pool.waiting(), 1)

        ## Send will never be called, so balance should be 0.
        self.assertFalse(waiter.ready())

        api.kill(killable)
Пример #21
0
    def test_killing_dormant(self):
        state = []

        def test():
            try:
                state.append('start')
                sleep(DELAY)
            except:
                state.append('except')
                # catching GreenletExit
                pass
            # when switching to hub, hub makes itself the parent of this greenlet,
            # thus after the function's done, the control will go to the parent
            # QQQ why the first sleep is not enough?
            sleep(0)
            state.append('finished')

        g = spawn(test)
        sleep(DELAY / 2)
        assert state == ['start'], state
        kill(g)
        # will not get there, unless switching is explicitly scheduled by kill
        assert state == ['start', 'except'], state
        sleep(DELAY)
        assert state == ['start', 'except', 'finished'], state
Пример #22
0
    def test_del_closes_socket(self):
        timer = api.exc_after(0.5, api.TimeoutError)

        def accept_once(listener):
            # delete/overwrite the original conn
            # object, only keeping the file object around
            # closing the file object should close everything
            try:
                conn, addr = listener.accept()
                conn = conn.makeGreenFile()
                conn.write('hello\n')
                conn.close()
                self.assertRaises(socket.error, conn.write, 'a')
            finally:
                listener.close()

        server = api.tcp_listener(('0.0.0.0', 0))
        killer = api.spawn(accept_once, server)
        client = api.connect_tcp(('127.0.0.1', server.getsockname()[1]))
        fd = client.makeGreenFile()
        client.close()
        assert fd.read() == b'hello\n'
        assert fd.read() == ''

        timer.cancel()
Пример #23
0
    def test_close_with_makefile(self):
        def accept_close_early(listener):
            # verify that the makefile and the socket are truly independent
            # by closing the socket prior to using the made file
            try:
                conn, addr = listener.accept()
                fd = conn.makeGreenFile()
                conn.close()
                fd.write('hello\n')
                fd.close()
                self.assertRaises(socket.error, fd.write, 'a')
                self.assertRaises(socket.error, conn.send, 'b')
            finally:
                listener.close()

        def accept_close_late(listener):
            # verify that the makefile and the socket are truly independent
            # by closing the made file and then sending a character
            try:
                conn, addr = listener.accept()
                fd = conn.makeGreenFile()
                fd.write('hello')
                fd.close()
                conn.send('\n')
                conn.close()
                self.assertRaises(socket.error, fd.write, 'a')
                self.assertRaises(socket.error, conn.send, 'b')
            finally:
                listener.close()

        def did_it_work(server):
            client = api.connect_tcp(('127.0.0.1', server.getsockname()[1]))
            fd = client.makeGreenFile()
            client.close()
            assert fd.readline() == b'hello\n'
            assert fd.read() == ''
            fd.close()

        server = api.tcp_listener(('0.0.0.0', 0))
        killer = api.spawn(accept_close_early, server)
        did_it_work(server)
        api.kill(killer)

        server = api.tcp_listener(('0.0.0.0', 0))
        killer = api.spawn(accept_close_late, server)
        did_it_work(server)
        api.kill(killer)
Пример #24
0
 def setUp(self):
     self.logfile = StringIO()
     self.site = Site()
     self.killer = api.spawn(wsgi.server,
                             api.tcp_listener(('0.0.0.0', 12346)),
                             self.site,
                             max_size=128,
                             log=self.logfile)
Пример #25
0
    def test_send_exc(self):
        log = []
        e = event()

        def waiter():
            try:
                result = e.wait()
                log.append(('received', result))
            except Exception as ex:
                log.append(('catched', ex))

        spawn(waiter)
        sleep(0)  # let waiter to block on e.wait()
        obj = Exception()
        e.send(exc=obj)
        sleep(0)
        assert log == [('catched', obj)], log
Пример #26
0
    def test_waiters_that_cancel(self):
        q = coros.queue()

        def do_receive(q, evt):
            api.exc_after(0, RuntimeError())
            try:
                result = q.wait()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        evt = coros.event()
        api.spawn(do_receive, q, evt)
        self.assertEqual(evt.wait(), 'timed out')

        q.send('hi')
        self.assertEqual(q.wait(), 'hi')
Пример #27
0
    def test_012_ssl_server(self):
        from eventlib import httpc

        def wsgi_app(environ, start_response):
            start_response('200 OK', {})
            return [environ['wsgi.input'].read()]

        certificate_file = os.path.join(os.path.dirname(__file__),
                                        'test_server.crt')
        private_key_file = os.path.join(os.path.dirname(__file__),
                                        'test_server.key')

        sock = api.ssl_listener(('', 4201), certificate_file, private_key_file)

        api.spawn(wsgi.server, sock, wsgi_app)

        result = httpc.post("https://localhost:4201/foo", "abc")
        self.assertEqual(result, 'abc')
Пример #28
0
    def test_two_bogus_waiters(self):
        def do_receive(q, evt):
            api.exc_after(0, RuntimeError())
            try:
                result = q.wait()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        q = coros.queue()
        e1 = coros.event()
        e2 = coros.event()
        api.spawn(do_receive, q, e1)
        api.spawn(do_receive, q, e2)
        api.sleep(0)
        q.send('sent')
        self.assertEqual(e1.wait(), 'timed out')
        self.assertEqual(e2.wait(), 'timed out')
        self.assertEqual(q.wait(), 'sent')
Пример #29
0
    def test_putting_to_queue(self):
        timer = api.exc_after(0.1, api.TimeoutError)
        size = 2
        self.pool = IntPool(min_size=0, max_size=size)
        queue = coros.queue()
        results = []

        def just_put(pool_item, index):
            self.pool.put(pool_item)
            queue.send(index)

        for index in xrange(size + 1):
            pool_item = self.pool.get()
            api.spawn(just_put, pool_item, index)

        while results != range(size + 1):
            x = queue.wait()
            results.append(x)
        timer.cancel()
Пример #30
0
    def test_ssl_proxy_redirects(self):
        # make sure that if the proxy returns a redirect, that httpc
        # successfully follows it (this was broken at one point)
        def ssl_proxy(sock):
            conn, addr = sock.accept()
            fd = conn.makefile()
            try:
                line = request = fd.readline()
                self.assertEqual(request,
                                 'GET https://localhost:1234 HTTP/1.1\r\n')
                while line.strip():  # eat request headers
                    line = fd.readline()

                # we're not going to actually proxy to localhost:1234,
                # we're just going to return a response on its behalf
                fd.write(
                    "HTTP/1.0 302 Found\r\nLocation: https://localhost:1234/2\r\n\r\n"
                )
            finally:
                fd.close()
                conn.close()

            # second request, for /2 target
            conn, addr = sock.accept()
            fd = conn.makefile()
            try:
                line = request = fd.readline()
                self.assertEqual(request,
                                 'GET https://localhost:1234/2 HTTP/1.1\r\n')
                while line.strip():  # eat request headers
                    line = fd.readline()
                fd.write("HTTP/1.0 200 OK\r\n\r\n")
            finally:
                fd.close()
                conn.close()
            sock.close()

        server = api.tcp_listener(('0.0.0.0', 5505))
        api.spawn(ssl_proxy, server)
        import os
        os.environ['ALL_PROXY'] = 'localhost:5505'
        httpc.get('https://localhost:1234', use_proxy=True, max_retries=1)
Пример #31
0
    def __init__(self, concurrency=1):
        """ Constructs an Actor, kicking off a new coroutine to process the messages.

        The concurrency argument specifies how many messages the actor will try
        to process concurrently.  If it is 1, the actor will process messages
        serially.
        """
        self._mailbox = collections.deque()
        self._event = event()
        self._killer = api.spawn(self.run_forever)
        self._pool = CoroutinePool(min_size=0, max_size=concurrency)
Пример #32
0
    def __init__(self, concurrency=1):
        """ Constructs an Actor, kicking off a new coroutine to process the messages.

        The concurrency argument specifies how many messages the actor will try
        to process concurrently.  If it is 1, the actor will process messages
        serially.
        """
        self._mailbox = collections.deque()
        self._event = event()
        self._killer = api.spawn(self.run_forever)
        self._pool = CoroutinePool(min_size=0, max_size=concurrency)
Пример #33
0
def execute(func, *args, **kw):
    """ Executes an operation asynchronously in a new coroutine, returning
    an event to retrieve the return value.

    This has the same api as the CoroutinePool.execute method; the only
    difference is that this one creates a new coroutine instead of drawing
    from a pool.

    >>> from eventlib import coros
    >>> evt = coros.execute(lambda a: ('foo', a), 1)
    >>> evt.wait()
    ('foo', 1)
    """
    evt = event()

    def _really_execute():
        evt.send(func(*args, **kw))

    api.spawn(_really_execute)
    return evt
Пример #34
0
def execute(func, *args, **kw):
    """ Executes an operation asynchronously in a new coroutine, returning
    an event to retrieve the return value.

    This has the same api as the CoroutinePool.execute method; the only
    difference is that this one creates a new coroutine instead of drawing
    from a pool.

    >>> from eventlib import coros
    >>> evt = coros.execute(lambda a: ('foo', a), 1)
    >>> evt.wait()
    ('foo', 1)
    """
    evt = event()

    def _really_execute():
        evt.send(func(*args, **kw))

    api.spawn(_really_execute)
    return evt
Пример #35
0
    import sys

    try:
        num = int(sys.argv[1])
    except:
        sys.exit("Supply number of test as an argument, 0, 1, 2 or 3")
    from twisted.internet import reactor

    def test():
        print block_on(reactor.resolver.getHostByName("www.google.com"))
        print block_on(reactor.resolver.getHostByName("###"))

    if num == 0:
        test()
    elif num == 1:
        spawn(test)
        from eventlib.api import sleep

        print "sleeping.."
        sleep(5)
        print "done sleeping.."
    elif num == 2:
        from eventlib.twistedutil import join_reactor

        spawn(test)
        reactor.run()
    elif num == 3:
        from eventlib.twistedutil import join_reactor

        print "fails because it's impossible to use block_on from the mainloop"
        reactor.callLater(0, test)
Пример #36
0
def start_new_thread(function, args=(), kwargs={}):
    g = spawn(function, *args, **kwargs)
    return get_ident(g)
Пример #37
0
def deferToGreenThread(func, *args, **kwargs):
    d = defer.Deferred()
    spawn(_putResultInDeferred, d, func, args, kwargs)
    return d
Пример #38
0
def callInGreenThread(func, *args, **kwargs):
    return spawn(func, *args, **kwargs)