From be0beed4036c2606f75da5e68b131f20a4a8dfc9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 18 May 2013 21:59:37 -0700 Subject: [PATCH 1/4] Some cleanups for the PyPy plugin: a) pep8 and such b) Made classes be newstyle c) Made the classes be created once, not once per request --- plugins/pypy/pypy_setup.py | 139 ++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 62 deletions(-) diff --git a/plugins/pypy/pypy_setup.py b/plugins/pypy/pypy_setup.py index 5c79f96d..777817e5 100644 --- a/plugins/pypy/pypy_setup.py +++ b/plugins/pypy/pypy_setup.py @@ -13,8 +13,8 @@ void (*uwsgi_pypy_hook_loader)(char *); void (*uwsgi_pypy_hook_request)(void *, int); struct iovec { - char *iov_base; - uint64_t iov_len; + char *iov_base; + uint64_t iov_len; }; struct uwsgi_opt { @@ -50,6 +50,7 @@ libc = ffi.dlopen(None) wsgi_application = None + @ffi.callback("void(char *)") def uwsgi_pypy_loader(module): global wsgi_application @@ -57,12 +58,71 @@ def uwsgi_pypy_loader(module): c = 'application' if ':' in m: m, c = m.split(':') - if '.' in m: + if '.' in m: mod = __import__(m, None, None, '*') else: mod = __import__(m) wsgi_application = getattr(mod, c) + +class WSGIfilewrapper(object): + def __init__(self, f, chunksize=0): + self.fd = f.fileno() + self.chunksize = chunksize + if hasattr(f, 'close'): + self.close = f.close + + def __getitem__(self, key): + data = self.filelike.read(self.blksize) + if data: + return data + raise IndexError + + +class WSGIinput(object): + def __init__(self, wsgi_req): + self.wsgi_req = wsgi_req + + def read(self, size=0): + rlen = ffi.new('int64_t *') + chunk = lib.uwsgi_request_body_read(self.wsgi_req, size, rlen) + if chunk != ffi.NULL: + return ffi.string(chunk, rlen[0]) + if rlen[0] < 0: + raise IOError("error reading wsgi.input") + raise IOError("error waiting for wsgi.input") + + def getline(self, hint=0): + rlen = ffi.new('int64_t *') + chunk = lib.uwsgi_request_body_readline(self.wsgi_req, hint, rlen) + if chunk != ffi.NULL: + return ffi.string(chunk, rlen[0]) + if rlen[0] < 0: + raise IOError("error reading line from wsgi.input") + raise IOError("error waiting for line on wsgi.input") + + def readline(self, hint=0): + return self.getline(hint) + + def readlines(self, hint=0): + lines = [] + while True: + chunk = self.getline(hint) + if len(chunk) == 0: + break + lines.append(chunk) + return lines + + def __iter__(self): + return self + + def __next__(self): + chunk = self.getline() + if len(chunk) == 0: + raise StopIteration + return chunk + + @ffi.callback("void(void *, int)") def uwsgi_pypy_wsgi_handler(wsgi_req, core): global wsgi_application @@ -76,62 +136,9 @@ def uwsgi_pypy_wsgi_handler(wsgi_req, core): lib.uwsgi_response_add_header(wsgi_req, ffi.new("char[]", hh[0]), len(hh[0]), ffi.new("char[]", hh[1]), len(hh[1])) return writer - class WSGIfilewrapper(): - def __init__(self, f, chunksize=0): - self.fd = f.fileno() - self.chunksize = chunksize - if hasattr(f, 'close'): - self.close = f.close - - def __getitem__(self, key): - data = self.filelike.read(self.blksize) - if data: - return data - raise IndexError - def sendfile(self): lib.uwsgi_response_sendfile_do(wsgi_req, self.fd, 0, 0) - class WSGIinput(): - def read(self, size=0): - rlen = ffi.new('int64_t *') - chunk = lib.uwsgi_request_body_read(wsgi_req, size, rlen) - if chunk != ffi.NULL: - return ffi.string(chunk, rlen[0]) - if rlen[0] < 0: - raise IOError("error reading wsgi.input") - raise IOError("error waiting for wsgi.input") - - def getline(self,hint=0): - rlen = ffi.new('int64_t *') - chunk = lib.uwsgi_request_body_readline(wsgi_req, hint, rlen) - if chunk != ffi.NULL: - return ffi.string(chunk, rlen[0]) - if rlen[0] < 0: - raise IOError("error reading line from wsgi.input") - raise IOError("error waiting for line on wsgi.input") - - def readline(self, hint=0): - return self.getline(hint) - - def readlines(self,hint=0): - lines = [] - for chunk in self.getline(hint): - if len(chunk) == 0: - break - lines.append(chunk) - return lines - - def __iter__(self): - return self - - def __next__(self): - chunk = self.getline() - if len(chunk) == 0: - raise StopIteration - return chunk - - environ = {} nv = ffi.new("uint16_t *") iov = lib.uwsgi_pypy_helper_environ(wsgi_req, nv) @@ -151,7 +158,7 @@ def uwsgi_pypy_wsgi_handler(wsgi_req, core): environ['uwsgi.core'] = core - response = wsgi_application(environ, start_response) + response = wsgi_application(environ, start_response) if type(response) is str: writer(response) else: @@ -178,7 +185,8 @@ import imp uwsgi = imp.new_module('uwsgi') sys.modules['uwsgi'] = uwsgi -uwsgi.version = ffi.string( lib.uwsgi_pypy_helper_version() ) +uwsgi.version = ffi.string(lib.uwsgi_pypy_helper_version()) + def uwsgi_pypy_uwsgi_register_signal(signum, kind, handler): uwsgi_gc.append(handler) @@ -186,29 +194,34 @@ def uwsgi_pypy_uwsgi_register_signal(signum, kind, handler): raise Exception("unable to register signal %d" % signum) uwsgi.register_signal = uwsgi_pypy_uwsgi_register_signal -class uwsgi_pypy_RPC(): + +class uwsgi_pypy_RPC(object): def __init__(self, func): self.func = func + def __call__(self, argc, argv, argvs, buf): pargs = [] for i in range(0, argc): - pargs.append(ffi.string(argv[i],argvs[i])) + pargs.append(ffi.string(argv[i], argvs[i])) response = self.func(*pargs) if len(response) > 0 and len(response) <= 65535: dst = ffi.buffer(buf, 65536) dst[:len(response)] = response return len(response) + def uwsgi_pypy_uwsgi_register_rpc(name, func, argc=0): uwsgi_gc.append(func) if lib.uwsgi_pypy_helper_register_rpc(ffi.new("char[]", name), argc, ffi.callback("int(int, char*[], int[], char*)", uwsgi_pypy_RPC(func))) < 0: raise Exception("unable to register rpc func %s" % name) uwsgi.register_rpc = uwsgi_pypy_uwsgi_register_rpc + def uwsgi_pypy_uwsgi_signal(signum): lib.uwsgi_pypy_helper_signal(signum) uwsgi.signal = uwsgi_pypy_uwsgi_signal + def uwsgi_pypy_uwsgi_cache_get(key, cache=ffi.NULL): vallen = ffi.new('uint64_t *') value = lib.uwsgi_cache_magic_get(key, len(key), vallen, ffi.NULL, cache) @@ -219,11 +232,13 @@ def uwsgi_pypy_uwsgi_cache_get(key, cache=ffi.NULL): return ret uwsgi.cache_get = uwsgi_pypy_uwsgi_cache_get + def uwsgi_pypy_uwsgi_add_timer(signum, secs): if lib.uwsgi_add_timer(signum, secs) < 0: raise Exception("unable to register timer") uwsgi.add_timer = uwsgi_pypy_uwsgi_add_timer + def uwsgi_pypy_uwsgi_add_file_monitor(signum, filename): if lib.uwsgi_add_file_monitor(signum, ffi.new("char[]", filename)) < 0: raise Exception("unable to register file monitor") @@ -235,7 +250,7 @@ populate uwsgi.opt uwsgi.opt = {} n_opts = ffi.new('int *') u_opts = lib.uwsgi_pypy_helper_opts(n_opts) -for i in range(0,n_opts[0]): +for i in range(0, n_opts[0]): k = ffi.string(u_opts[i].key) if u_opts[i].value == ffi.NULL: v = True @@ -249,4 +264,4 @@ for i in range(0,n_opts[0]): else: uwsgi.opt[k] = v -print "Initialized PyPy with Python",sys.version +print "Initialized PyPy with Python", sys.version From a4434349e56e2ce612f5e2d7dab62c686d18a893 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 18 May 2013 22:03:55 -0700 Subject: [PATCH 2/4] whoops, a few small fixse --- plugins/pypy/pypy_setup.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/pypy/pypy_setup.py b/plugins/pypy/pypy_setup.py index 777817e5..cffb14f2 100644 --- a/plugins/pypy/pypy_setup.py +++ b/plugins/pypy/pypy_setup.py @@ -66,7 +66,8 @@ def uwsgi_pypy_loader(module): class WSGIfilewrapper(object): - def __init__(self, f, chunksize=0): + def __init__(self, wsgi_req, f, chunksize=0): + self.wsgi_req = wsgi_req self.fd = f.fileno() self.chunksize = chunksize if hasattr(f, 'close'): @@ -78,6 +79,9 @@ class WSGIfilewrapper(object): return data raise IndexError + def sendfile(self): + lib.uwsgi_response_sendfile_do(self.wsgi_req, self.fd, 0, 0) + class WSGIinput(object): def __init__(self, wsgi_req): @@ -136,9 +140,6 @@ def uwsgi_pypy_wsgi_handler(wsgi_req, core): lib.uwsgi_response_add_header(wsgi_req, ffi.new("char[]", hh[0]), len(hh[0]), ffi.new("char[]", hh[1]), len(hh[1])) return writer - def sendfile(self): - lib.uwsgi_response_sendfile_do(wsgi_req, self.fd, 0, 0) - environ = {} nv = ffi.new("uint16_t *") iov = lib.uwsgi_pypy_helper_environ(wsgi_req, nv) @@ -151,10 +152,10 @@ def uwsgi_pypy_wsgi_handler(wsgi_req, core): if environ['HTTPS'] in ('on', 'ON', 'On', '1', 'true', 'TRUE', 'True'): scheme = 'https' environ['wsgi.url_scheme'] = environ.get('UWSGI_SCHEME', scheme) - environ['wsgi.input'] = WSGIinput() + environ['wsgi.input'] = WSGIinput(wsgi_req) environ['wsgi.errors'] = sys.stderr environ['wsgi.run_once'] = False - environ['wsgi.file_wrapper'] = WSGIfilewrapper + environ['wsgi.file_wrapper'] = lambda f, chunksize=0: WSGIfilewrapper(wsgi_req, f, chunksize) environ['uwsgi.core'] = core From 6615d1b90c8ff25c9fd061154c0f16f919f79fd4 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 18 May 2013 22:06:36 -0700 Subject: [PATCH 3/4] Catch a more precise error --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bb06aa33..d25b6774 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ def get_profile(): try: import __pypy__ is_pypy = True - except: + except ImportError: pass if is_pypy: profile = os.environ.get('UWSGI_PROFILE', 'buildconf/pypy.ini') From 22b2f325e029578477245c25b82b2cbb08eb324b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 18 May 2013 22:09:24 -0700 Subject: [PATCH 4/4] removed a method with a nonsense implementation --- plugins/pypy/pypy_setup.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/pypy/pypy_setup.py b/plugins/pypy/pypy_setup.py index cffb14f2..fbe8edc5 100644 --- a/plugins/pypy/pypy_setup.py +++ b/plugins/pypy/pypy_setup.py @@ -73,12 +73,6 @@ class WSGIfilewrapper(object): if hasattr(f, 'close'): self.close = f.close - def __getitem__(self, key): - data = self.filelike.read(self.blksize) - if data: - return data - raise IndexError - def sendfile(self): lib.uwsgi_response_sendfile_do(self.wsgi_req, self.fd, 0, 0)