def serve( application, host=None, port=None, handler=None, ssl_pem=None, ssl_context=None, server_version=None, protocol_version=None, start_loop=True, socket_timeout=4.2, request_queue_size=10, response_timeout=4.2, request_timeout=4.2, server_status=None, explicit_flush=False, **kwargs ): """ Serves your ``application`` over HTTP via WSGI interface ``host`` This is the ipaddress to bind to (or a hostname if your nameserver is properly configured). This defaults to 127.0.0.1, which is not a public interface. ``port`` The port to run on, defaults to 8080 for HTTP, or 4443 for HTTPS. This can be a string or an integer value. ``handler`` This is the HTTP request handler to use, it defaults to ``WSGIHandler`` in this module. ``server_version`` The version of the server as reported in HTTP response line. This defaults to something like "PasteWSGIServer/0.5". Many servers hide their code-base identity with a name like 'Amnesiac/1.0' ``protocol_version`` This sets the protocol used by the server, by default ``HTTP/1.0``. There is some support for ``HTTP/1.1``, which defaults to nicer keep-alive connections. This server supports ``100 Continue``, but does not yet support HTTP/1.1 Chunked Encoding. Hence, if you use HTTP/1.1, you're somewhat in error since chunked coding is a mandatory requirement of a HTTP/1.1 server. If you specify HTTP/1.1, every response *must* have a ``Content-Length`` and you must be careful not to read past the end of the socket. ``start_loop`` This specifies if the server loop (aka ``server.serve_forever()``) should be called; it defaults to ``True``. ``socket_timeout`` This specifies the maximum amount of time that a connection to a given client will be kept open. At this time, it is a rude disconnect, but at a later time it might follow the RFC a bit more closely. ``request_queue_size`` listen(2) parameter ``response_timeout`` Maximum time to wait for the response to be completed by the app stack ``request_timeout`` iop timeout on request reading operations ``server_status`` This specifies path where coev/coewsgi status be output. ``explicit_flush`` Force packets to be sent at the end of each HTTP-keepalive request by toggling TCP_NODELAY socket option. """ assert not handler, "foreign handlers are prohibited" assert not ssl_context, "SSL/TLS not supported" assert not ssl_pem, "SSL/TLS not supported" # assert converters.asbool(start_loop), "WTF?" sys.setcheckinterval(10000000) host = host or "127.0.0.1" if not port: if ":" in host: host, port = host.split(":", 1) else: port = 8080 server_address = (host, int(port)) handler = CoevWSGIHandler if server_version: handler.server_version = server_version handler.sys_version = None if protocol_version: assert protocol_version in ("HTTP/0.9", "HTTP/1.0", "HTTP/1.1") handler.protocol_version = protocol_version if server_status: application = CoevStatsMiddleware(server_status, application) server = CoevWSGIServer(application, server_address, handler, **kwargs) protocol = "http" host, port = server.server_address el = logging.getLogger("coewsgi.serve") if host == "0.0.0.0": el.info("serving on 0.0.0.0:%s view at %s://127.0.0.1:%s", port, protocol, port) else: el.info("serving on %s://%s:%s", protocol, host, port) el.info("request_queue_size: %d", request_queue_size) el.info("socket_timeout: %0.3f", socket_timeout) el.info("request_timeout: %0.3f", request_timeout) el.info("response_timeout: %0.3f", response_timeout) def rim(server): try: server.bind() server.serve() except KeyboardInterrupt: # allow CTRL+C to shutdown el.info("exiting on KeyboardInterrupt") pass except: el.exception("uh-oh") finally: server.unbind() thread.start_new_thread(rim, (server,)) try: coev.scheduler() except: el.exception("exception out of scheduler:") el.info("server shut down")
import gevent from gevent.pool import Group from gevent.hub import sleep horde = Group() for x in xrange(num): horde.spawn(stack_filler, depth, sleep) gevent.sleep(settle) print("settle period over, {:.2f} sw/sec, testing".format(SWITCH_COUNT/(1.0*settle))) SWITCH_COUNT=0 gevent.sleep(period) print("testing period over, {:.2f} sw/sec".format(SWITCH_COUNT/(1.0*period))) horde.kill() ap = argparse.ArgumentParser() ap.add_argument('-depth', metavar='depth', type=int, help='recursion level/stack depth at switch', default=32) ap.add_argument('-period', metavar='seconds', type=int, help='test period after settle-down', default=10) ap.add_argument('-settle', metavar='seconds', type=int, help='settle period before measurement', default=2) ap.add_argument('-num', metavar='coevs', type=int, help='number of coroutines to launch', default=512) pa = ap.parse_args() try: import coev, thread thread.start_new_thread(test_coev, (pa.num, pa.depth, pa.period, pa.settle)) coev.scheduler() except ImportError, cer: test_gevent(pa.num, pa.depth, pa.period, pa.settle)