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. 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 greenlib
from eventlet import httpc
from eventlet.hubs import hub 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_POLLIN = 0x01
WSGI_POLLOUT = 0x04 WSGI_POLLOUT = 0x04
import traceback
class Hub(hub.BaseHub): class Hub(hub.BaseHub):
def add_descriptor(self, fileno, read=None, write=None, exc=None): def __init__(self, *args, **kw):
super(Hub, self).add_descriptor(fileno, read, write, exc) hub.BaseHub.__init__(self, *args, **kw)
self._connection_wrappers = {}
if read is not None: def add_descriptor(self, fileno, read=None, write=None, exc=None):
self.poll_register(fileno, WSGI_POLLIN) print "ADD DESCRIPTOR", fileno, read, write, exc
elif write is not None: traceback.print_stack()
self.poll_register(fileno, WSGI_POLLOUT)
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): def remove_descriptor(self, fileno):
super(Hub, self).remove_descriptor(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): def wait(self, seconds=0):
if seconds is not None: to_call = getattr(self, 'to_call', None)
self.sleep(int(seconds*1000)) 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()