Jan-Philip Gehrcke avatar Jan-Philip Gehrcke committed 0ba71c1

Add WSGI+multiprocessing example.

Comments (0)

Files changed (1)

examples/wsgimultiprocessing.py

+# Copyright 2013, Jan-Philip Gehrcke. See LICENSE for details.
+import gevent
+from gevent.wsgi import WSGIServer
+import gipc
+import urllib2
+import time
+
+"""
+Multiple clients (running in greenlets that concurrently run in a child
+process) request a response from a WSGIServer running in the parent. Each
+response is generated by a child process, i.e. each client connection makes the server process spawn a child.
+
+A greenlet in the parent, the `servelet`, runs the WSGIServer. Each client
+connection is handled in its own greenlet running the `hello_world` function.
+This delegates the response creation to a child process. The child process
+transfers the response back to the greenlet in the parent process via a gipc
+pipe. This yields the response to the client.
+
+Each client greenlet validates the response and terminates.
+
+Output on my test system: 100 clients were served within 0.43 s.
+"""
+
+
+MSG = "response"
+N = 100
+
+
+def main():
+    http_server = WSGIServer(('localhost', 0), hello_world, log=False)
+    servelet = gevent.spawn(serve, http_server)
+    # Wait for server being bound to socket.
+    while True:
+        if http_server.address[1] != 0:
+            break
+        gevent.sleep(0.05)
+    client = gipc.start_process(
+        target=child_test_wsgi_scenario_client,
+        args=(http_server.address, ))
+    client.join()
+    servelet.kill()
+    servelet.join()
+
+
+def serve(http_server):
+    http_server.serve_forever()
+
+
+def hello_world(environ, start_response):
+    # Generate response in child process.
+    with gipc.pipe() as (reader, writer):
+        start_response('200 OK', [('Content-Type', 'text/html')])
+        rg = gipc.start_process(
+            target=child_test_wsgi_scenario_respgen,
+            args=(writer, ))
+        response = reader.get()
+        rg.join()
+    yield response
+
+
+def child_test_wsgi_scenario_respgen(writer):
+    writer.put(MSG)
+
+
+def child_test_wsgi_scenario_client(server_address):
+    def get():
+        assert urllib2.urlopen("http://%s:%s/" % server_address).read() == MSG
+
+    t1 = time.time()
+    clientlets = [gevent.spawn(get) for _ in xrange(N)]
+    gevent.joinall(clientlets)
+    duration = time.time() - t1
+    print "%s clients were served within %.2f s." % (N, duration)
+
+
+if __name__ == "__main__":
+    main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.