Update the nginx mod_wsgi support to the latest mod_wsgi semantics; there's a bug that's currently preventing it from working, though.

This commit is contained in:
donovan
2008-05-08 09:17:08 -07:00
parent c61ce07bbf
commit 001936a6f2
2 changed files with 133 additions and 81 deletions

View File

@@ -23,31 +23,150 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from os.path import abspath, dirname
import sys
import traceback
sys.stdout = sys.stderr
mydir = dirname(dirname(dirname(abspath(__file__))))
if mydir not in sys.path:
sys.path.append(mydir)
from eventlet import api
from eventlet import greenlib
from eventlet import httpc
from eventlet.hubs import hub
from eventlet import util
util.wrap_socket_with_coroutine_socket()
def hello_world(env, start_response):
result = httpc.get('http://www.google.com/')
start_response('200 OK', [('Content-type', 'text/plain')])
return [result]
def wrap_application(master, env, start_response):
try:
real_application = api.named(env['eventlet_nginx_wsgi_app'])
except:
real_application = hello_world
result = real_application(env, start_response)
master.switch((result, None))
return None, None
class StartResponse(object):
def __call__(self, *args):
self.args = args
pythonpath_already_set = False
WSGI_POLLIN = 0x01
WSGI_POLLOUT = 0x04
import traceback
class Hub(hub.BaseHub):
def add_descriptor(self, fileno, read=None, write=None, exc=None):
super(Hub, self).add_descriptor(fileno, read, write, exc)
def __init__(self, *args, **kw):
hub.BaseHub.__init__(self, *args, **kw)
self._connection_wrappers = {}
if read is not None:
self.poll_register(fileno, WSGI_POLLIN)
elif write is not None:
self.poll_register(fileno, WSGI_POLLOUT)
def add_descriptor(self, fileno, read=None, write=None, exc=None):
print "ADD DESCRIPTOR", fileno, read, write, exc
traceback.print_stack()
super(Hub, self).add_descriptor(fileno, read, write, exc)
flag = 0
if read:
flag |= WSGI_POLLIN
if write:
flag |= WSGI_POLLOUT
conn = self.connection_wrapper(fileno)
self._connection_wrappers[fileno] = conn
print "POLL REGISTER", flag
self.poll_register(conn, flag)
def remove_descriptor(self, fileno):
super(Hub, self).remove_descriptor(fileno)
self.poll_unregister(fileno)
try:
self.poll_unregister(self._connection_wrappers[fileno])
except RuntimeError:
pass
def wait(self, seconds=None):
if seconds is not None:
self.sleep(int(seconds*1000))
def wait(self, seconds=0):
to_call = getattr(self, 'to_call', None)
print "WAIT", self, to_call
if to_call:
print "CALL TOCALL"
result = to_call[0](to_call[1])
del self.to_call
return result
greenlib.switch(self.current_application, self.poll(int(seconds*1000)))
greenlib.switch(self.current_application)
def application(self, env, start_response):
print "ENV",env
self.poll_register = env['ngx.poll_register']
self.poll_unregister = env['ngx.poll_unregister']
self.poll = env['ngx.poll']
self.connection_wrapper = env['ngx.connection_wrapper']
self.current_application = api.getcurrent()
slave = api.greenlet.greenlet(wrap_application)
response = StartResponse()
result = slave.switch(
api.getcurrent(), env, response)
while True:
self.current_application = api.getcurrent()
print "RESULT", result, callable(result[0])
if result and callable(result[0]):
print "YIELDING!"
yield ''
print "AFTER YIELD!"
conn, flags = result[0]()
fileno = conn.fileno()
if flags & WSGI_POLLIN:
self.readers[fileno](fileno)
elif flags & WSGI_POLLOUT:
self.writers[fileno](fileno)
print "POLL STATE", conn, flags, dir(conn)
else:
start_response(*response.args)
if isinstance(result, tuple):
for x in result[0]:
yield x
else:
for x in result:
yield x
return
result = self.switch()
if not isinstance(result, tuple):
result = (result, None) ## TODO Fix greenlib's return values
def application(env, start_response):
hub = api.get_hub()
if not isinstance(hub, Hub):
api.use_hub(sys.modules[Hub.__module__])
hub = api.get_hub()
global pythonpath_already_set
if not pythonpath_already_set:
pythonpath = env.get('eventlet_python_path', '').split(':')
for seg in pythonpath:
if seg not in sys.path:
sys.path.append(seg)
return hub.application(env, start_response)

View File

@@ -1,67 +0,0 @@
import sys
import traceback
sys.path.insert(0, '/Users/donovan/Code/mulib-hg')
sys.stdout = sys.stderr
from eventlet import api
from eventlet import httpc
from eventlet.hubs import nginx
def old_real_application(env, start_response):
#result = httpc.get('http://127.0.0.1:8081/')
start_response('200 OK', [('Content-type', 'text/plain')])
#sys.stderr.write("RESULT %r" % (result, ))
return 'hello'
def wrap_application(master, env, start_response):
real_application = api.named(env['eventlet_nginx_wsgi_app'])
result = real_application(env, start_response)
## Should catch exception and return here?
#sys.stderr.write("RESULT2 %r" % (result, ))
master.switch((result, None))
return None, None
class StartResponse(object):
def __init__(self, start_response):
self.start_response = start_response
def __call__(self, *args):
self.args = args
def application(env, start_response):
hub = api.get_hub()
if not isinstance(hub, nginx.Hub):
api.use_hub(nginx)
hub.poll_register = env['ngx.poll_register']
hub.poll_unregister = env['ngx.poll_unregister']
hub.sleep = env['ngx.sleep']
hub.current_application = api.getcurrent()
slave = api.greenlet.greenlet(wrap_application)
response = StartResponse(start_response)
result = slave.switch(
hub.current_application, env, response)
while True:
#sys.stderr.write("RESULT3 %r" % (result, ))
if result is None or result == (None, None):
yield ''
else:
start_response(*response.args)
if isinstance(result, tuple):
for x in result[0]:
yield x
else:
for x in result:
yield x
return
result = hub.switch()