3

I'm using web.py framework. For debugging purposes, I'd like to force all requests to be handled by a single thread, or simulate such behaviour with a mutex. How can I do that?

2 Answers2

5

Let me suggest something like this, but it will lock only current application stack over your controller method.

import web
from threading import Lock

urls = ("/", "Index")


class Index:

    def GET(self):
        # This will be locked
        return "hello world"


def mutex_processor():
    mutex = Lock()

    def processor_func(handle):
        mutex.acquire()
        try:
            return handle()
        finally:
            mutex.release()
    return processor_func

app = web.application(urls, globals())

app.add_processor(mutex_processor())

if __name__ == "__main__":
    app.run()

UPD: if you need to lock the whole application stack then you probably have to wrap app.wsgifunc with your own WSGI middleware. To get an idea check my answer to this question.

Community
  • 1
  • 1
Andrey Kuzmin
  • 4,479
  • 2
  • 23
  • 28
2

To get things decently into a single thread debugging mode, the web.py app can be run with a single threaded WSGI server.

Such server is "almost" offered by web.py itself as web.httpserver.runbasic() which uses Python's builtin BaseHTTPServer.HTTPServer - but also SocketServer.ThreadingMixIn . This ThreadingMixIn however can be blocked by something like this:

# single threaded execution of web.py app

app = web.application(urls, globals())

# suppress ThreadingMixIn in web.httpserver.runbasic()
import SocketServer
class NoThreadingMixIn:
    pass
assert SocketServer.ThreadingMixIn
SocketServer.ThreadingMixIn = NoThreadingMixIn

web.httpserver.runbasic(app.wsgifunc())

Or you could replicate the rather short web.httpserver.runbasic() code.

kxr
  • 4,841
  • 1
  • 49
  • 32