Search code examples
pythonmultithreadingwsgiwerkzeug

Starting a separate thread in a WSGI environment


Having trouble finding other cases where something like this has been implemented.

I have a WSGI app that was built with Werkzeug, and I'd like to run some background cleanup processes in the same context as the WSGI application if possible (I'd rather not have them separate scripts in cron, that way when the application is started as a service, the necessary background tasks are running as well.) The webserver being used is Apache with mod_wsgi.

Let's assume a really basic WSGI example, since the content being served isn't really at issue. I'm going to use the one Pocoo has at the official Werkzeug docs:

class Shortly(object):

    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])

    def dispatch_request(self, request):
        return Response('Hello World!')

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)


def create_app(redis_host='localhost', redis_port=6379):
    app = Shortly({
        'redis_host':       redis_host,
        'redis_port':       redis_port
    })
    return app

Would it be feasible to start another non-blocking thread of execution within the create_app function that would go ahead and perform these tasks on a timed interval? Does mod_wsgi run an app 'continously' as this would require?

def create_app(redis_host='localhost', redis_port=6379):
    app = Shortly({
        'redis_host':       redis_host,
        'redis_port':       redis_port
    })

    #do some other stuff in a separate thread while the webapp is running
    task = threading.Thread(target=DBCleanup, args=(query, stuff))
    task.start()
    return app

Solution

  • Read:

    http://code.google.com/p/modwsgi/wiki/RegisteringCleanupCode

    and see code monitor example in:

    http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Monitoring_For_Code_Changes

    The first has general examples of how to cleanup things on end of request and end of process.

    The second shows how can create background thread to do stuff on period basis and properly try and close down background thread on process exit.