Can you have an object shared across multiple WSGI threads/processes (and in a manner that would work on both *NIX and Windows)?
The basic premise: (1) I have a WSGI front end that will connect to a back end server. I have a serialization class, that contains rules on how to serialize/unserialize various objects, including classes specific to this project. As such, it needs to have some setup telling it how to handle custom objects. However, it is otherwise stateless - multiple threads can access it at the same time to serialize their data without issue. (2) There are sockets to connect to the back end. I'd rather have a socket pool than create/destroy every time there's a connection.
Note: I don't mind a solution where there are multiple instances of (1) and (2), but ideally, I'd like them created/initialized as few times as possible. I'm not sure about the internals, but if a thread loops rather than closing and having the server reopen on a new request, it would be fine to have one data set per thread (and hence, the socket and serializer are initialized once per thread, but reused each subsequent call it handles.) Actually having one socket per thread, if that's how it works, would be best, since I wouldn't need a socket pool and have to deal with mutexes.
Note: this is not sessions and has nothing to do with sessions. This shouldn't care who is making the call to the server. It's only about tweaking performance on systems that have slow thread creation, or a lot of memory but relatively slow CPUs.
Edit 2: The below code will give some info on how your system shares variables. You'll need to load the page a few times to get some diagnostics...
from datetime import *;
from threading import *;
import thread;
from cgi import escape;
from os import getpid;
count = 0;
responses = [];
lock = RLock();
start_ident = "%08X::%08X" % (thread.get_ident(), getpid());
show_env = False;
def application(environ, start_response):
status = '200 OK';
this_ident = "%08X::%08X" % (thread.get_ident(), getpid());
lock.acquire();
current_response = """<HR>
<B>Request Number</B>: """ + str(count) + """<BR>
<B>Request Time</B>: """ + str(datetime.now()) + """<BR>
<B>Current Thread</B>: """ + this_ident + """<BR>
<B>Initializing Thread</B>: """ + start_ident + """<BR>
Multithread/Multiprocess: """ + str(environ["wsgi.multithread"]) + "/" + str(environ["wsgi.multiprocess"]) +"""<BR>
"""
global count;
count += 1;
global responses;
responses.append(current_response)
if(len(responses) >= 100):
responses = responses[1:];
lock.release();
output="<HTML><BODY>";
if(show_env):
output+="<H2>Environment</H2><TABLE><TR><TD>Key</TD><TD>Value</TD></TR>";
for k in environ.keys():
output += "<TR><TD>"+escape(k)+"</TD><TD>"+escape(str(environ[k]))+"</TD></TR>";
output+="</TABLE>";
output += "<H2>Response History</H2>";
for r in responses:
output += r;
output+="</BODY></HTML>"
response_headers = [('Content-type', 'text/html'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]