예제 #1
0
 def test_spawn(self):
     p = GreenPool(4)
     waiters = []
     for i in xrange(10):
         waiters.append(p.spawn(passthru, i))
     results = [waiter.wait() for waiter in waiters]
     self.assertEquals(results, list(xrange(10)))
예제 #2
0
 def test_spawn(self):
     p = GreenPool(4)
     waiters = []
     for i in xrange(10):
         waiters.append(p.spawn(passthru, i))
     results = [waiter.wait() for waiter in waiters]
     self.assertEquals(results, list(xrange(10)))
예제 #3
0
    def test_resize(self):
        pool = GreenPool(2)
        evt = Event()

        def wait_long_time(e):
            e.wait()

        pool.spawn(wait_long_time, evt)
        pool.spawn(wait_long_time, evt)
        self.assertEquals(pool.free(), 0)
        self.assert_pool_has_free(pool, 0)

        # verify that the pool discards excess items put into it
        pool.resize(1)

        # cause the wait_long_time functions to return, which will
        # trigger puts to the pool
        evt.send(None)
        sleep(0)
        sleep(0)

        self.assertEquals(pool.free(), 1)
        self.assert_pool_has_free(pool, 1)

        # resize larger and assert that there are more free items
        pool.resize(2)
        self.assertEquals(pool.free(), 2)
        self.assert_pool_has_free(pool, 2)
예제 #4
0
    def test_waiting(self):
        pool = GreenPool(1)
        done = Event()

        def consume():
            done.wait()

        def waiter(pool):
            evt = pool.spawn(consume)
            evt.wait()

        waiters = []
        waiters.append(spawn(waiter, pool))
        sleep(0)
        self.assertEqual(pool.waiting(), 0)
        waiters.append(spawn(waiter, pool))
        sleep(0)
        self.assertEqual(pool.waiting(), 1)
        waiters.append(spawn(waiter, pool))
        sleep(0)
        self.assertEqual(pool.waiting(), 2)
        done.send(None)
        for w in waiters:
            w.wait()
        self.assertEqual(pool.waiting(), 0)
예제 #5
0
    def imap_memory_check(self, concurrency):
        # checks that imap is strictly
        # ordered and consumes a constant amount of memory
        p = GreenPool(concurrency)
        count = 1000
        it = p.imap(passthru, xrange(count))
        latest = -1
        while True:
            try:
                i = it.next()
            except StopIteration:
                break

            if latest == -1:
                gc.collect()
                initial_obj_count = len(gc.get_objects())
            self.assert_(i > latest)
            latest = i
            if latest % 5 == 0:
                sleep(0.001)
            if latest % 10 == 0:
                gc.collect()
                objs_created = len(gc.get_objects()) - initial_obj_count
                self.assert_(objs_created < 25 * concurrency, objs_created)
                # make sure we got to the end
        self.assertEquals(latest, count - 1)
예제 #6
0
    def imap_memory_check (self, concurrency):
        # checks that imap is strictly
        # ordered and consumes a constant amount of memory
        p = GreenPool(concurrency)
        count = 1000
        it = p.imap(passthru, xrange(count))
        latest = -1
        while True:
            try:
                i = it.next()
            except StopIteration:
                break

            if latest == -1:
                gc.collect()
                initial_obj_count = len(gc.get_objects())
            self.assert_(i > latest)
            latest = i
            if latest % 5 == 0:
                sleep(0.001)
            if latest % 10 == 0:
                gc.collect()
                objs_created = len(gc.get_objects()) - initial_obj_count
                self.assert_(objs_created < 25 * concurrency, objs_created)
                # make sure we got to the end
        self.assertEquals(latest, count - 1)
예제 #7
0
    def test_execute_async(self):
        done = Event()

        def some_work():
            done.send()

        pool = GreenPool(2)
        pool.spawn(some_work)
        done.wait()
예제 #8
0
    def test_execute(self):
        value = 'return value'

        def some_work():
            return value

        pool = GreenPool(2)
        worker = pool.spawn(some_work)
        self.assertEqual(value, worker.wait())
예제 #9
0
    def test_execute_async(self):
        done = Event()

        def some_work():
            done.send()

        pool = GreenPool(2)
        pool.spawn(some_work)
        done.wait()
예제 #10
0
    def test_execute(self):
        value = "return value"

        def some_work():
            return value

        pool = GreenPool(2)
        worker = pool.spawn(some_work)
        self.assertEqual(value, worker.wait())
예제 #11
0
        def subtest(intpool_size, pool_size, num_executes):
            def run(int_pool):
                token = int_pool.get()
                sleep(0.0001)
                int_pool.put(token)
                return token

            int_pool = IntPool(intpool_size)
            pool = GreenPool(pool_size)
            for ix in xrange(num_executes):
                pool.spawn(run, int_pool)
            pool.waitall()
예제 #12
0
    def test_spawn_n(self):
        p = GreenPool(4)
        results_closure = []

        def do_something(a):
            sleep(0.01)
            results_closure.append(a)

        for i in xrange(10):
            p.spawn(do_something, i)
        p.waitall()
        self.assertEquals(sorted(results_closure), range(10))
예제 #13
0
 def test_exceptions(self):
     p = GreenPool(2)
     for m in (p.spawn, p.spawn_n):
         self.assert_pool_has_free(p, 2)
         m(raiser, RuntimeError())
         self.assert_pool_has_free(p, 1)
         p.waitall()
         self.assert_pool_has_free(p, 2)
         m(raiser, greenlet.GreenletExit)
         self.assert_pool_has_free(p, 1)
         p.waitall()
         self.assert_pool_has_free(p, 2)
예제 #14
0
    def test_timer_cancel(self):
        # this test verifies that local timers are not fired
        # outside of the context of the spawn method
        timer_fired = []

        def fire_timer():
            timer_fired.append(True)

        def some_work():
            hubs.get_hub().schedule_call_local(0, fire_timer)

        pool = GreenPool(2)
        worker = pool.spawn(some_work)
        worker.wait()
        sleep(0)
        self.assertEquals(timer_fired, [])
예제 #15
0
    def test_timer_cancel(self):
        # this test verifies that local timers are not fired
        # outside of the context of the spawn method
        timer_fired = []

        def fire_timer():
            timer_fired.append(True)

        def some_work():
            hubs.get_hub().schedule_call_local(0, fire_timer)

        pool = GreenPool(2)
        worker = pool.spawn(some_work)
        worker.wait()
        sleep(0)
        self.assertEquals(timer_fired, [])
예제 #16
0
    def test_multiple_coros(self):
        evt = Event()
        results = []

        def producer():
            results.append('prod')
            evt.send()

        def consumer():
            results.append('cons1')
            evt.wait()
            results.append('cons2')

        pool = GreenPool(2)
        done = pool.spawn(consumer)
        pool.spawn_n(producer)
        done.wait()
        self.assertEquals(['cons1', 'prod', 'cons2'], results)
예제 #17
0
    def test_reentrant(self):
        pool = GreenPool(1)

        def reenter():
            waiter = pool.spawn(lambda a: a, "reenter")
            self.assertEqual("reenter", waiter.wait())

        outer_waiter = pool.spawn(reenter)
        outer_waiter.wait()

        evt = Event()

        def reenter_async():
            pool.spawn(lambda a: a, "reenter")
            evt.send("done")

        pool.spawn(reenter_async)
        evt.wait()
예제 #18
0
    def test_reentrant(self):
        pool = GreenPool(1)

        def reenter():
            waiter = pool.spawn(lambda a: a, 'reenter')
            self.assertEqual('reenter', waiter.wait())

        outer_waiter = pool.spawn(reenter)
        outer_waiter.wait()

        evt = Event()

        def reenter_async():
            pool.spawn(lambda a: a, 'reenter')
            evt.send('done')

        pool.spawn(reenter_async)
        evt.wait()
예제 #19
0
    def test_multiple_coros(self):
        evt = Event()
        results = []

        def producer():
            results.append("prod")
            evt.send()

        def consumer():
            results.append("cons1")
            evt.wait()
            results.append("cons2")

        pool = GreenPool(2)
        done = pool.spawn(consumer)
        pool.spawn_n(producer)
        done.wait()
        self.assertEquals(["cons1", "prod", "cons2"], results)
예제 #20
0
    def test_pool_smash(self):
        """
        The premise is that a coroutine in a Pool tries to get a token out of a token pool but times out
        before getting the token.  We verify that neither pool is adversely affected by this situation.
        """
        from evy import pools

        pool = GreenPool(1)
        tp = pools.TokenPool(max_size=1)
        token = tp.get()  # empty out the pool

        def do_receive(tp):
            _timer = Timeout(0, RuntimeError())
            try:
                t = tp.get()
                self.fail("Shouldn't have recieved anything from the pool")
            except RuntimeError:
                return "timed out"
            else:
                _timer.cancel()

        # the spawn makes the token pool expect that coroutine, but then
        # immediately cuts bait
        e1 = pool.spawn(do_receive, tp)
        self.assertEquals(e1.wait(), "timed out")

        # the pool can get some random item back
        def send_wakeup(tp):
            tp.put("wakeup")

        gt = spawn(send_wakeup, tp)

        # now we ask the pool to run something else, which should not
        # be affected by the previous send at all
        def resume():
            return "resumed"

        e2 = pool.spawn(resume)
        self.assertEquals(e2.wait(), "resumed")

        # we should be able to get out the thing we put in there, too
        self.assertEquals(tp.get(), "wakeup")
        gt.wait()
예제 #21
0
파일: test_thread.py 프로젝트: inercia/evy
    def test_no_leaking (self):
        refs = weakref.WeakKeyDictionary()
        my_local = corolocal.local()

        class X(object):
            pass

        def do_something (i):
            o = X()
            refs[o] = True
            my_local.foo = o

        p = GreenPool()
        for i in xrange(100):
            p.spawn(do_something, i)
        p.waitall()
        del p
        # at this point all our coros have terminated
        self.assertEqual(len(refs), 1)
예제 #22
0
    def test_pool_smash(self):
        """
        The premise is that a coroutine in a Pool tries to get a token out of a token pool but times out
        before getting the token.  We verify that neither pool is adversely affected by this situation.
        """
        from evy import pools

        pool = GreenPool(1)
        tp = pools.TokenPool(max_size=1)
        token = tp.get()  # empty out the pool

        def do_receive(tp):
            _timer = Timeout(0, RuntimeError())
            try:
                t = tp.get()
                self.fail("Shouldn't have recieved anything from the pool")
            except RuntimeError:
                return 'timed out'
            else:
                _timer.cancel()

        # the spawn makes the token pool expect that coroutine, but then
        # immediately cuts bait
        e1 = pool.spawn(do_receive, tp)
        self.assertEquals(e1.wait(), 'timed out')

        # the pool can get some random item back
        def send_wakeup(tp):
            tp.put('wakeup')

        gt = spawn(send_wakeup, tp)

        # now we ask the pool to run something else, which should not
        # be affected by the previous send at all
        def resume():
            return 'resumed'

        e2 = pool.spawn(resume)
        self.assertEquals(e2.wait(), 'resumed')

        # we should be able to get out the thing we put in there, too
        self.assertEquals(tp.get(), 'wakeup')
        gt.wait()
예제 #23
0
def serve(sock, handle, concurrency=1000):
    """
    Runs a server on the supplied socket.  Calls the function *handle* in a
    separate greenthread for every incoming client connection.  *handle* takes
    two arguments: the client socket object, and the client address::
        
        def myhandle(client_sock, client_addr):
            print "client connected", client_addr
        
        evy.serve(evy.listen(('127.0.0.1', 9999)), myhandle)
        
    Returning from *handle* closes the client socket.
     
    :func:`serve` blocks the calling greenthread; it won't return until 
    the server completes.  If you desire an immediate return,
    spawn a new greenthread for :func:`serve`.
      
    Any uncaught exceptions raised in *handle* are raised as exceptions 
    from :func:`serve`, terminating the server, so be sure to be aware of the 
    exceptions your application can raise.  The return value of *handle* is 
    ignored.      
      
    Raise a :class:`~evy.StopServe` exception to gracefully terminate the 
    server -- that's the only way to get the server() function to return rather 
    than raise.

    The value in *concurrency* controls the maximum number of
    greenthreads that will be open at any time handling requests.  When
    the server hits the concurrency limit, it stops accepting new
    connections until the existing ones complete.
    """
    pool = GreenPool(concurrency)
    server_gt = getcurrent()

    while True:
        try:
            conn, addr = sock.accept()
            gt = pool.spawn(handle, conn, addr)
            gt.link(_stop_checker, server_gt, conn)
            conn, addr, gt = None, None, None
        except StopServe:
            return
예제 #24
0
파일: convenience.py 프로젝트: inercia/evy
def serve (sock, handle, concurrency = 1000):
    """
    Runs a server on the supplied socket.  Calls the function *handle* in a
    separate greenthread for every incoming client connection.  *handle* takes
    two arguments: the client socket object, and the client address::
        
        def myhandle(client_sock, client_addr):
            print "client connected", client_addr
        
        evy.serve(evy.listen(('127.0.0.1', 9999)), myhandle)
        
    Returning from *handle* closes the client socket.
     
    :func:`serve` blocks the calling greenthread; it won't return until 
    the server completes.  If you desire an immediate return,
    spawn a new greenthread for :func:`serve`.
      
    Any uncaught exceptions raised in *handle* are raised as exceptions 
    from :func:`serve`, terminating the server, so be sure to be aware of the 
    exceptions your application can raise.  The return value of *handle* is 
    ignored.      
      
    Raise a :class:`~evy.StopServe` exception to gracefully terminate the 
    server -- that's the only way to get the server() function to return rather 
    than raise.

    The value in *concurrency* controls the maximum number of
    greenthreads that will be open at any time handling requests.  When
    the server hits the concurrency limit, it stops accepting new
    connections until the existing ones complete.
    """
    pool = GreenPool(concurrency)
    server_gt = getcurrent()

    while True:
        try:
            conn, addr = sock.accept()
            gt = pool.spawn(handle, conn, addr)
            gt.link(_stop_checker, server_gt, conn)
            conn, addr, gt = None, None, None
        except StopServe:
            return
예제 #25
0
파일: test_pools.py 프로젝트: inercia/evy
    def test_create_contention (self):
        creates = [0]

        def sleep_create ():
            creates[0] += 1
            sleep()
            return "slept"

        p = pools.Pool(max_size = 4, create = sleep_create)

        def do_get ():
            x = p.get()
            self.assertEquals(x, "slept")
            p.put(x)

        gp = GreenPool()
        for i in xrange(100):
            gp.spawn_n(do_get)
        gp.waitall()
        self.assertEquals(creates[0], 4)
예제 #26
0
    def test_waiting(self):
        pool = GreenPool(1)
        done = Event()

        def consume():
            done.wait()

        def waiter(pool):
            evt = pool.spawn(consume)
            evt.wait()

        waiters = []
        waiters.append(spawn(waiter, pool))
        sleep(0)
        self.assertEqual(pool.waiting(), 0)
        waiters.append(spawn(waiter, pool))
        sleep(0)
        self.assertEqual(pool.waiting(), 1)
        waiters.append(spawn(waiter, pool))
        sleep(0)
        self.assertEqual(pool.waiting(), 2)
        done.send(None)
        for w in waiters:
            w.wait()
        self.assertEqual(pool.waiting(), 0)
예제 #27
0
    def test_imap_raises(self):
        """
        testing the case where the function raises an exception both that the caller sees that exception, and that the iterator
        continues to be usable to get the rest of the items
        """
        p = GreenPool(4)

        def raiser(item):
            if item == 1 or item == 7:
                raise RuntimeError("intentional error")
            else:
                return item

        it = p.imap(raiser, xrange(10))
        results = []
        while True:
            try:
                results.append(it.next())
            except RuntimeError:
                results.append('r')
            except StopIteration:
                break
        self.assertEquals(results, [0, 'r', 2, 3, 4, 5, 6, 'r', 8, 9])
예제 #28
0
    def test_constructing_from_pool(self):
        pool = GreenPool(2)
        pile1 = GreenPile(pool)
        pile2 = GreenPile(pool)

        def bunch_of_work(pile, unique):
            for i in xrange(10):
                pile.spawn(passthru, i + unique)

        spawn(bunch_of_work, pile1, 0)
        spawn(bunch_of_work, pile2, 100)
        sleep(0)
        self.assertEquals(list(pile2), list(xrange(100, 110)))
        self.assertEquals(list(pile1), list(xrange(10)))
예제 #29
0
    def test_imap_raises(self):
        """
        testing the case where the function raises an exception both that the caller sees that exception, and that the iterator
        continues to be usable to get the rest of the items
        """
        p = GreenPool(4)

        def raiser(item):
            if item == 1 or item == 7:
                raise RuntimeError("intentional error")
            else:
                return item

        it = p.imap(raiser, xrange(10))
        results = []
        while True:
            try:
                results.append(it.next())
            except RuntimeError:
                results.append("r")
            except StopIteration:
                break
        self.assertEquals(results, [0, "r", 2, 3, 4, 5, 6, "r", 8, 9])
예제 #30
0
    def test_stderr_raising(self):
        # testing that really egregious errors in the error handling code
        # (that prints tracebacks to stderr) don't cause the pool to lose
        # any members
        import sys

        pool = GreenPool(1)

        def crash(*args, **kw):
            raise RuntimeError("Whoa")

        class FakeFile(object):
            write = crash

        # we're going to do this by causing the traceback.print_exc in
        # safe_apply to raise an exception and thus exit _main_loop
        normal_err = sys.stderr
        try:
            sys.stderr = FakeFile()
            waiter = pool.spawn(crash)
            self.assertRaises(RuntimeError, waiter.wait)
            # the pool should have something free at this point since the
            # waiter returned
            # GreenPool change: if an exception is raised during execution of a link,
            # the rest of the links are scheduled to be executed on the next hub iteration
            # this introduces a delay in updating pool.sem which makes pool.free() report 0
            # therefore, sleep:
            sleep(0)
            self.assertEqual(pool.free(), 1)
            # shouldn't block when trying to get
            t = Timeout(0.1)
            try:
                pool.spawn(sleep, 1)
            finally:
                t.cancel()
        finally:
            sys.stderr = normal_err
예제 #31
0
        def subtest(intpool_size, pool_size, num_executes):
            def run(int_pool):
                token = int_pool.get()
                sleep(0.0001)
                int_pool.put(token)
                return token

            int_pool = IntPool(intpool_size)
            pool = GreenPool(pool_size)
            for ix in xrange(num_executes):
                pool.spawn(run, int_pool)
            pool.waitall()
예제 #32
0
    def test_spawn_n(self):
        p = GreenPool(4)
        results_closure = []

        def do_something(a):
            sleep(0.01)
            results_closure.append(a)

        for i in xrange(10):
            p.spawn(do_something, i)
        p.waitall()
        self.assertEquals(sorted(results_closure), range(10))
예제 #33
0
 def test_exceptions(self):
     p = GreenPool(2)
     for m in (p.spawn, p.spawn_n):
         self.assert_pool_has_free(p, 2)
         m(raiser, RuntimeError())
         self.assert_pool_has_free(p, 1)
         p.waitall()
         self.assert_pool_has_free(p, 2)
         m(raiser, greenlet.GreenletExit)
         self.assert_pool_has_free(p, 1)
         p.waitall()
         self.assert_pool_has_free(p, 2)
예제 #34
0
    def test_no_leaking(self):
        refs = weakref.WeakKeyDictionary()
        my_local = corolocal.local()

        class X(object):
            pass

        def do_something(i):
            o = X()
            refs[o] = True
            my_local.foo = o

        p = GreenPool()
        for i in xrange(100):
            p.spawn(do_something, i)
        p.waitall()
        del p
        # at this point all our coros have terminated
        self.assertEqual(len(refs), 1)
예제 #35
0
    def test_create_contention(self):
        creates = [0]

        def sleep_create():
            creates[0] += 1
            sleep()
            return "slept"

        p = pools.Pool(max_size=4, create=sleep_create)

        def do_get():
            x = p.get()
            self.assertEquals(x, "slept")
            p.put(x)

        gp = GreenPool()
        for i in xrange(100):
            gp.spawn_n(do_get)
        gp.waitall()
        self.assertEquals(creates[0], 4)
예제 #36
0
    def test_stderr_raising(self):
        # testing that really egregious errors in the error handling code
        # (that prints tracebacks to stderr) don't cause the pool to lose
        # any members
        import sys

        pool = GreenPool(1)

        def crash(*args, **kw):
            raise RuntimeError("Whoa")

        class FakeFile(object):
            write = crash

        # we're going to do this by causing the traceback.print_exc in
        # safe_apply to raise an exception and thus exit _main_loop
        normal_err = sys.stderr
        try:
            sys.stderr = FakeFile()
            waiter = pool.spawn(crash)
            self.assertRaises(RuntimeError, waiter.wait)
            # the pool should have something free at this point since the
            # waiter returned
            # GreenPool change: if an exception is raised during execution of a link,
            # the rest of the links are scheduled to be executed on the next hub iteration
            # this introduces a delay in updating pool.sem which makes pool.free() report 0
            # therefore, sleep:
            sleep(0)
            self.assertEqual(pool.free(), 1)
            # shouldn't block when trying to get
            t = Timeout(0.1)
            try:
                pool.spawn(sleep, 1)
            finally:
                t.cancel()
        finally:
            sys.stderr = normal_err
예제 #37
0
 def test_imap_multi_args(self):
     p = GreenPool(4)
     result_list = list(p.imap(passthru2, xrange(10), xrange(10, 20)))
     self.assertEquals(result_list, list(itertools.izip(xrange(10), xrange(10, 20))))
예제 #38
0
 def test_imap_nonefunc(self):
     p = GreenPool(4)
     result_list = list(p.imap(None, xrange(10)))
     self.assertEquals(result_list, [(x,) for x in xrange(10)])
예제 #39
0
 def test_execute(self):
     p = GreenPool()
     evt = p.spawn(lambda a: ("foo", a), 1)
     self.assertEqual(evt.wait(), ("foo", 1))
예제 #40
0
 def test_recursive_waitall(self):
     p = GreenPool()
     gt = p.spawn(p.waitall)
     self.assertRaises(AssertionError, gt.wait)
예제 #41
0
def server(sock,
           site,
           log=None,
           environ=None,
           max_size=None,
           max_http_version=DEFAULT_MAX_HTTP_VERSION,
           protocol=HttpProtocol,
           server_event=None,
           minimum_chunk_size=None,
           log_x_forwarded_for=True,
           custom_pool=None,
           keepalive=True,
           log_output=True,
           log_format=DEFAULT_LOG_FORMAT,
           url_length_limit=MAX_REQUEST_LINE,
           debug=True):
    """  Start up a wsgi server handling requests from the supplied server
    socket.  This function loops forever.  The *sock* object will be closed after server exits,
    but the underlying file descriptor will remain open, so if you have a dup() of *sock*,
    it will remain usable.

    :param sock: Server socket, must be already bound to a port and listening.
    :param site: WSGI application function.
    :param log: File-like object that logs should be written to.  If not specified, sys.stderr is used.
    :param environ: Additional parameters that go into the environ dictionary of every request.
    :param max_size: Maximum number of client connections opened at any time by this server.
    :param max_http_version: Set to "HTTP/1.0" to make the server pretend it only supports HTTP 1.0.  This can help with applications or clients that don't behave properly using HTTP 1.1.
    :param protocol: Protocol class.  Deprecated.
    :param server_event: Used to collect the Server object.  Deprecated.
    :param minimum_chunk_size: Minimum size in bytes for http chunks.  This  can be used to improve performance of applications which yield many small strings, though using it technically violates the WSGI spec.
    :param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for header in addition to the actual client ip address in the 'client_ip' field of the log line.
    :param custom_pool: A custom GreenPool instance which is used to spawn client green threads.  If this is supplied, max_size is ignored.
    :param keepalive: If set to False, disables keepalives on the server; all connections will be closed after serving one request.
    :param log_output: A Boolean indicating if the server will log data or not.
    :param log_format: A python format string that is used as the template to generate log lines.  The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds.  The default is a good example of how to use it.
    :param url_length_limit: A maximum allowed length of the request url. If exceeded, 414 error is returned.
    :param debug: True if the server should send exception tracebacks to the clients on 500 errors.  If False, the server will respond with empty bodies.
    """
    serv = Server(sock,
                  sock.getsockname(),
                  site,
                  log,
                  environ=environ,
                  max_http_version=max_http_version,
                  protocol=protocol,
                  minimum_chunk_size=minimum_chunk_size,
                  log_x_forwarded_for=log_x_forwarded_for,
                  keepalive=keepalive,
                  log_output=log_output,
                  log_format=log_format,
                  url_length_limit=url_length_limit,
                  debug=debug)
    if server_event is not None:
        server_event.send(serv)
    if max_size is None:
        max_size = DEFAULT_MAX_SIMULTANEOUS_REQUESTS
    if custom_pool is not None:
        pool = custom_pool
    else:
        pool = GreenPool(max_size)
    try:
        host, port = sock.getsockname()[:2]
        port = ':%s' % (port, )
        if hasattr(sock, 'do_handshake'):
            scheme = 'https'
            if port == ':443':
                port = ''
        else:
            scheme = 'http'
            if port == ':80':
                port = ''

        serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" %
                       (os.getpid(), scheme, host, port))
        while True:
            try:
                client_socket = sock.accept()
                try:
                    pool.spawn_n(serv.process_request, client_socket)
                except AttributeError:
                    warnings.warn("wsgi's pool should be an instance of "\
                                  "evy.greenpool.GreenPool, is %s. Please convert your"\
                                  " call site to use GreenPool instead" % type(pool),
                                  DeprecationWarning, stacklevel = 2)
                    pool.execute_async(serv.process_request, client_socket)
            except ACCEPT_EXCEPTIONS, e:
                if get_errno(e) not in ACCEPT_ERRNO:
                    raise
            except (KeyboardInterrupt, SystemExit):
                serv.log.write("wsgi exiting\n")
                break
예제 #42
0
 def test_execute(self):
     p = GreenPool()
     evt = p.spawn(lambda a: ('foo', a), 1)
     self.assertEqual(evt.wait(), ('foo', 1))
예제 #43
0
    def test_resize(self):
        pool = GreenPool(2)
        evt = Event()

        def wait_long_time(e):
            e.wait()

        pool.spawn(wait_long_time, evt)
        pool.spawn(wait_long_time, evt)
        self.assertEquals(pool.free(), 0)
        self.assert_pool_has_free(pool, 0)

        # verify that the pool discards excess items put into it
        pool.resize(1)

        # cause the wait_long_time functions to return, which will
        # trigger puts to the pool
        evt.send(None)
        sleep(0)
        sleep(0)

        self.assertEquals(pool.free(), 1)
        self.assert_pool_has_free(pool, 1)

        # resize larger and assert that there are more free items
        pool.resize(2)
        self.assertEquals(pool.free(), 2)
        self.assert_pool_has_free(pool, 2)
예제 #44
0
 def test_imap_multi_args(self):
     p = GreenPool(4)
     result_list = list(p.imap(passthru2, xrange(10), xrange(10, 20)))
     self.assertEquals(result_list,
                       list(itertools.izip(xrange(10), xrange(10, 20))))
예제 #45
0
 def test_waitall_on_nothing(self):
     p = GreenPool()
     p.waitall()
예제 #46
0
파일: wsgi.py 프로젝트: inercia/evy
def server (sock, site,
            log = None,
            environ = None,
            max_size = None,
            max_http_version = DEFAULT_MAX_HTTP_VERSION,
            protocol = HttpProtocol,
            server_event = None,
            minimum_chunk_size = None,
            log_x_forwarded_for = True,
            custom_pool = None,
            keepalive = True,
            log_output = True,
            log_format = DEFAULT_LOG_FORMAT,
            url_length_limit = MAX_REQUEST_LINE,
            debug = True):
    """  Start up a wsgi server handling requests from the supplied server
    socket.  This function loops forever.  The *sock* object will be closed after server exits,
    but the underlying file descriptor will remain open, so if you have a dup() of *sock*,
    it will remain usable.

    :param sock: Server socket, must be already bound to a port and listening.
    :param site: WSGI application function.
    :param log: File-like object that logs should be written to.  If not specified, sys.stderr is used.
    :param environ: Additional parameters that go into the environ dictionary of every request.
    :param max_size: Maximum number of client connections opened at any time by this server.
    :param max_http_version: Set to "HTTP/1.0" to make the server pretend it only supports HTTP 1.0.  This can help with applications or clients that don't behave properly using HTTP 1.1.
    :param protocol: Protocol class.  Deprecated.
    :param server_event: Used to collect the Server object.  Deprecated.
    :param minimum_chunk_size: Minimum size in bytes for http chunks.  This  can be used to improve performance of applications which yield many small strings, though using it technically violates the WSGI spec.
    :param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for header in addition to the actual client ip address in the 'client_ip' field of the log line.
    :param custom_pool: A custom GreenPool instance which is used to spawn client green threads.  If this is supplied, max_size is ignored.
    :param keepalive: If set to False, disables keepalives on the server; all connections will be closed after serving one request.
    :param log_output: A Boolean indicating if the server will log data or not.
    :param log_format: A python format string that is used as the template to generate log lines.  The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds.  The default is a good example of how to use it.
    :param url_length_limit: A maximum allowed length of the request url. If exceeded, 414 error is returned.
    :param debug: True if the server should send exception tracebacks to the clients on 500 errors.  If False, the server will respond with empty bodies.
    """
    serv = Server(sock, sock.getsockname(),
                  site, log,
                  environ = environ,
                  max_http_version = max_http_version,
                  protocol = protocol,
                  minimum_chunk_size = minimum_chunk_size,
                  log_x_forwarded_for = log_x_forwarded_for,
                  keepalive = keepalive,
                  log_output = log_output,
                  log_format = log_format,
                  url_length_limit = url_length_limit,
                  debug = debug)
    if server_event is not None:
        server_event.send(serv)
    if max_size is None:
        max_size = DEFAULT_MAX_SIMULTANEOUS_REQUESTS
    if custom_pool is not None:
        pool = custom_pool
    else:
        pool = GreenPool(max_size)
    try:
        host, port = sock.getsockname()[:2]
        port = ':%s' % (port, )
        if hasattr(sock, 'do_handshake'):
            scheme = 'https'
            if port == ':443':
                port = ''
        else:
            scheme = 'http'
            if port == ':80':
                port = ''

        serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % (
            os.getpid(), scheme, host, port))
        while True:
            try:
                client_socket = sock.accept()
                try:
                    pool.spawn_n(serv.process_request, client_socket)
                except AttributeError:
                    warnings.warn("wsgi's pool should be an instance of "\
                                  "evy.greenpool.GreenPool, is %s. Please convert your"\
                                  " call site to use GreenPool instead" % type(pool),
                                  DeprecationWarning, stacklevel = 2)
                    pool.execute_async(serv.process_request, client_socket)
            except ACCEPT_EXCEPTIONS, e:
                if get_errno(e) not in ACCEPT_ERRNO:
                    raise
            except (KeyboardInterrupt, SystemExit):
                serv.log.write("wsgi exiting\n")
                break
예제 #47
0
    def test_spawn_n_2(self):
        p = GreenPool(2)
        self.assertEqual(p.free(), 2)
        r = []

        def foo(a):
            r.append(a)

        gt = p.spawn(foo, 1)
        self.assertEqual(p.free(), 1)
        gt.wait()
        self.assertEqual(r, [1])
        sleep(0)
        self.assertEqual(p.free(), 2)

        #Once the pool is exhausted, spawning forces a yield.
        p.spawn_n(foo, 2)
        self.assertEqual(1, p.free())
        self.assertEqual(r, [1])

        p.spawn_n(foo, 3)
        self.assertEqual(0, p.free())
        self.assertEqual(r, [1])

        p.spawn_n(foo, 4)
        self.assertEqual(set(r), set([1, 2, 3]))
        sleep(0)
        self.assertEqual(set(r), set([1, 2, 3, 4]))
예제 #48
0
 def test_imap(self):
     p = GreenPool(4)
     result_list = list(p.imap(passthru, xrange(10)))
     self.assertEquals(result_list, list(xrange(10)))
예제 #49
0
 def test_starmap(self):
     p = GreenPool(4)
     result_list = list(p.starmap(passthru, [(x,) for x in xrange(10)]))
     self.assertEquals(result_list, range(10))
예제 #50
0
 def test_empty_imap(self):
     p = GreenPool(4)
     result_iter = p.imap(passthru, [])
     self.assertRaises(StopIteration, result_iter.next)
예제 #51
0
 def test_starmap(self):
     p = GreenPool(4)
     result_list = list(p.starmap(passthru, [(x, ) for x in xrange(10)]))
     self.assertEquals(result_list, range(10))
예제 #52
0
 def test_waitall_on_nothing(self):
     p = GreenPool()
     p.waitall()
예제 #53
0
 def test_imap(self):
     p = GreenPool(4)
     result_list = list(p.imap(passthru, xrange(10)))
     self.assertEquals(result_list, list(xrange(10)))
예제 #54
0
    def test_spawn_n_2(self):
        p = GreenPool(2)
        self.assertEqual(p.free(), 2)
        r = []

        def foo(a):
            r.append(a)

        gt = p.spawn(foo, 1)
        self.assertEqual(p.free(), 1)
        gt.wait()
        self.assertEqual(r, [1])
        sleep(0)
        self.assertEqual(p.free(), 2)

        # Once the pool is exhausted, spawning forces a yield.
        p.spawn_n(foo, 2)
        self.assertEqual(1, p.free())
        self.assertEqual(r, [1])

        p.spawn_n(foo, 3)
        self.assertEqual(0, p.free())
        self.assertEqual(r, [1])

        p.spawn_n(foo, 4)
        self.assertEqual(set(r), set([1, 2, 3]))
        sleep(0)
        self.assertEqual(set(r), set([1, 2, 3, 4]))
예제 #55
0
 def test_empty_imap(self):
     p = GreenPool(4)
     result_iter = p.imap(passthru, [])
     self.assertRaises(StopIteration, result_iter.next)
예제 #56
0
 def test_imap_nonefunc(self):
     p = GreenPool(4)
     result_list = list(p.imap(None, xrange(10)))
     self.assertEquals(result_list, [(x, ) for x in xrange(10)])
예제 #57
0
파일: spawn.py 프로젝트: PlumpMath/evy
 def setup():
     global pool
     pool = GreenPool(iters)
예제 #58
0
 def test_recursive_waitall(self):
     p = GreenPool()
     gt = p.spawn(p.waitall)
     self.assertRaises(AssertionError, gt.wait)