[Web-SIG] Re: Regarding the WSGI draft

Ian Bicking ianb at colorstudy.com
Sat Aug 28 00:09:11 CEST 2004

Phillip J. Eby wrote:
>> I happened to be playing with just such a thing:
>> http://colorstudy.com/cgi-bin/viewcvs.cgi/trunk/WSGI/pycgiwrapper.py?rev=206&view=log 
> Wow; you certainly thought this through more than I did.  E.g. your 
> model for dealing with threads.  The part for dealing with missing 
> threads/threading though should probably use dummy_threading, though.

I figure if threads are missing, then we better not be in a 
wsgi.threaded environment, and if it's not threaded server then I don't 
use the threads or threading modules.

> Also, I notice that you're using multiple 'environ' replacements for 
> some reason, even though any use of it is going to be wrapped in a 
> global thread lock.  So, the '_environs' dictionary seems superfluous.  
> A minimal approach to adjusting the FieldStorage class could be:
> cgi.FieldStorage.__init__.im_func.func_defaults=(None,None,"",environ,0,0)
> which will make the default environ be the one you want.  Doing that, 
> and replacing 'os.environ' for the request's duration (and putting them 
> back when done) seem to be required.  (Note that code that doesn't use 
> the 'cgi' module but directly checks os.environ won't work with the 
> current state of things.)

Maybe other people don't use os.environ, but I always have a lot when 
doing cgi scripts, so I want to handle that case.  It had actually never 
occurred to me before to access environ through the cgi module...

> Hm.  Actually, I just looked and it looks like you're not wrapping the 
> execution in the global mutex, but you really need to because not only 
> are sys.std* global, CGI apps aren't generally written to be multithreaded.

Well, there's basically two code paths, the multithreaded and the 
multiprocess.  I thought about the multithreaded more, but have only 
tested the multi-process.

In both cases I try to replace sys.stdout and os.environ.  I forgot to 
put things back the way they were with the multiprocess technique, so 
it's a little broken now.  With the multithreaded case, it uses the 
thread ID to figure out what stream or environment you will be looking 
at, so it doesn't need a lock around run_script -- each thread sees a 
stdout and environ that is appropriate for it.  I guess I could just 
change stdin too and not worry about fidding with the cgi module at all.

Though it can cause problems.  E.g., if instead of the cgi server 
passing sys.stdout.write, it passed:

def write(s):

That would cause all sorts of problems.  Unless it used 
sys.__stdout__.write(s); I don't know if that would be a good or bad 
style.  That's what I did to work around my bug.

Anyway, the whole thing is a bit of a hack, so I don't expect it to work 
seemlessly with all scripts or all servers, though hopefully without 
heroic modifications it would be possible.  MoinMoin would be an 
excellent test, as I believe it is hopelessly bound to the cgi module, 
but would benefit nicely from running on a different environment, at 
least long-running multi-process.

> Don't forget: WSGIServer has *not* been updated to PEP 333 yet; it's 
> still based on the old streaming approach!  I've been too busy updating 
> the spec (and replying to every thread) to update the code.  :)

Hmm... I don't even remember what the old spec looked like anymore. 
I'll give it a look-see.

Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org

More information about the Web-SIG mailing list