views:

168

answers:

3

I'm writing a small web server for testing purposes using python, BasicHTTPServer and SimpleHTTPServer. It looks like it's processing one request at a time. Is there any way to make it a little faster without messing around too deeply? Basicly my code looks as the following and I'd like to keep it this simple ;)

os.chdir(webroot)
httpd = BaseHTTPServer.HTTPServer(("", port), SimpleHTTPServer.SimpleHTTPRequestHandler)
print("Serving directory %s on port %i" %(webroot, port) )
try:
 httpd.serve_forever()
except KeyboardInterrupt:
 print("Server stopped.")
+3  A: 

You can make your own threading or forking class with a mixin inheritance from SocketServer:

import SocketServer
import BaseHTTPServer

class ThreadingHTTPServer(SocketServer.ThreadingMixin, BaseHttpServer.HTTPServer):
    pass

This has its limits as it doesn't use a thread pool, is limited by the GIT, etc, but it could help a little (with relatively little effort). Remember that requests will be served simultaneously by multiple threads, so be sure to put proper locking around accesses to global/shared data (unless such data's immutable after startup) done in the course of serving a request.

This SO question covers the same ground (not particularly at length).

Alex Martelli
Sadly I'm stuck on 16 requests per second - with 1 concurrent request as well as with 10.
braindump
@braindump, if you're on any form of Unix (basically anything except Windows), try a ForkingMixin instead of the ThreadingMixin, it might serve you better, esp. if you're on a multicore CPU. Otherwise, you'll really need to move to some kind of "real" server (Tornado, for example: see http://www.tornadoweb.org/ -- simple, and very high performance per http://bret.appspot.com/entry/tornado-web-server ).
Alex Martelli
@Alex, I'm on Gentoo Linux on an ARM-based CPU. Thanks for your hint regarding Forking, it's much better now, even if it's not good ;)But for my intention, it's okay. (On 10 concurrent requests, I got 60 requests per second. Lighttpd reaches ~400 requests per second on the same machine)
braindump
@braindump, lighttpd's based on an async approach, I believe, just like Tornado, which I recommended. But if 60 QPS are OK for your purposes, there's no real need for you to check if Tornado would reach 300, 400, or whatever;-).
Alex Martelli
A: 

Depending on what your requirements are, another option might be to hook in Paste. Though, based on your example, it may be overkill. Something to keep in the toolbox.

McJeff
A: 

You might also look at CherryPy -- it's pretty simple, too, and has multiple request threads with no additional effort. Although your needs may be modest now, CP has a lot of nice capabilities that may benefit you in the future.

jgarbers