Development & Design Blog

Hosting Multiple WSGI Applications with Apache

So yesterday, I was trying to run a second instance of my TG2.0 application under Apache 2. I needed a demo, hosted under another subdirectory, for a client.

Piece of cake, right?

I’m running mod_wsgi 2.3 and Python 2.5.4. Apache 2 is compiled with the Unix Prefork MPM [1], so I’m running mod_wsgi in embedded mode [2].

I added another line to my virtualhost include, so I had two WSGIScriptAliases:

WSGIScriptAlias /my_app /home/myuser/myapp/wsgi_scripts/deployment.wsgi
WSGIScriptAlias /my_app_demo /home/myuser/myapp/wsgi_scripts/deployment.wsgi

I restarted Apache, and visited http://myhost/my_app, and everything loaded fine.

Then I visited http://myhost/my_app_demo, and got a 404 page (this is the deployment way of dealing with an error).

I checked my Apache error_log. There was a long stack trace, ending with:

RuntimeError: class.__dict__ not accessible in restricted mode

To test thoroughly before seeking help, I restarted Apache again, then visited http://myhost/my_app_demo. Everything loaded fine.
Then I visited http://myhost/my_app, and met with the same error as above.

It seems that whichever application was run first somehow got control of the necessary resources, and whatever application was started afterward got stuck in a stripped-down python environment.

A google search revealed a discussion [3] on the mailing list. The fellow in the thread seemed to be having problems running even a single instance of his application, but the error was similar enough to my own that I decided to try Graham Dumpleton’s advice. I added the following line to my Apache conf (before my virtual host definitions):

WSGIApplicationGroup %{GLOBAL}

I restarted Apache for the final time. Success!

I decided to look into why this is. Graham had mentioned something about python sub-interpreters in the mailing list thread [3]. I found a post about python sub interpreters [4] at stackoverflow and the c-python docs on sub interpreters [5].

Basically: C-Python provides an API to spawn mostly-separate interpreters within the same interpreter process. mod_wsgi takes advantage of this for running multiple applications within the same python process. The issue is that some C modules don’t play nicely with this functionality. I haven’t figured out which extension it is yet.

Anyway, the above WSGIApplicationGroup directive [6] tells mod_wsgi not to use the sub-interpreter functionality, and run all applications inside the same global interpreter. I’m not sure how that works yet, but it does!

References

  1. mod_wsgi docs on Processes and Threads (See the “The UNIX ‘prefork’ MPM” section)
  2. mod_wsgi docs Introduction (See the “Modes of Operation” section)
  3. Turbogears Mailing List thread with the above error
  4. Python Sub-Interpreter article on Stack Overflow
  5. C-Python docs on Sub-Interpreters
  6. mod_wsgi WSGIApplicationGroup directive docs
  • Graham Dumpleton Says:

    I’m not sure it is safe to run two TG instances in same interpreter, which using WSGIApplicationGroup with value of %{GLOBAL} for both would do. Just because you use prefork MPM doesn’t mean you can’t use daemon mode, so you would be better off delegating each to their own daemon process.

    WSGIDaemonProcess app1 processes=2 threads=1
    WSGIDaemonProcess app2 processes=2 threads=2

    WSGIScriptAlias /my_app /home/myuser/myapp/wsgi_scripts/deployment.wsgi
    WSGIScriptAlias /my_app_demo /home/myuser/myapp/wsgi_scripts/deployment.wsgi

    WSGIProcessGroup app1

    WSGIProcessGroup app2

    If need be, you could still use WSGIApplicationGroup set to %{GLOBAL} which means each would run in main interpreter of their respective processes.

    Note, I have assumed you need single threading, but if multithread safe mode, then instead use:

    WSGIDaemonProcess app1
    WSGIDaemonProcess app2

    This will default to single process for each with thread pool of 15 threads in the process.
    Hope this blog comment mode doesn’t stuff with the configuration formatting too much.

  • Graham Dumpleton Says:

    Ahhhhh, it swallowed up all the Location tags. One last try:

    <Location /my_app>
    WSGIProcessGroup app1
    </Location>

    <Location /my_app_demo>
    WSGIProcessGroup app2
    </Location>

  • Pete Says:

    A slightly off topic question, but could you please tell me what font you use for the simple station and mediaplex logos?

  • Anthony Theocharis Says:

    Graham, thanks so much for your advice.

    I haven’t had a chance to try it out yet, but as soon as I do, I’ll post back here.

Leave a Reply