From 688d1d3b7548550010e83e52765110edca18dbdb Mon Sep 17 00:00:00 2001 From: Aldur Date: Tue, 23 Sep 2014 11:30:35 +0200 Subject: [PATCH] fixed python3 support in spooler decorators --- core/async.c | 3 ++- plugins/asyncio/asyncio.c | 9 +++++++-- uwsgi.h | 1 + uwsgidecorators.py | 29 +++++++++++++++++++++++++++-- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/core/async.c b/core/async.c index 41651fdf..6c89ed2a 100644 --- a/core/async.c +++ b/core/async.c @@ -369,7 +369,8 @@ void async_schedule_to_req_green(void) { uwsgi.schedule_fix(wsgi_req); } // switch after each yield - uwsgi.schedule_to_main(wsgi_req); + if (uwsgi.schedule_to_main) + uwsgi.schedule_to_main(wsgi_req); } #ifdef UWSGI_ROUTING diff --git a/plugins/asyncio/asyncio.c b/plugins/asyncio/asyncio.c index 14be58f9..2a1415ba 100644 --- a/plugins/asyncio/asyncio.c +++ b/plugins/asyncio/asyncio.c @@ -312,8 +312,6 @@ static void asyncio_loop() { uwsgi.wait_write_hook = uwsgi_asyncio_wait_write_hook; uwsgi.wait_read_hook = uwsgi_asyncio_wait_read_hook; - uwsgi.schedule_fix = uwsgi_asyncio_schedule_fix; - if (uwsgi.async < 2) { uwsgi_log("the asyncio loop engine requires async mode (--async )\n"); exit(1); @@ -323,6 +321,13 @@ static void asyncio_loop() { uwsgi_log("*** DANGER *** asyncio mode without coroutine/greenthread engine loaded !!!\n"); } + if (!uwsgi.schedule_to_req) { + uwsgi.schedule_to_req = async_schedule_to_req_green; + } + else { + uwsgi.schedule_fix = uwsgi_asyncio_schedule_fix; + } + PyObject *asyncio = PyImport_ImportModule("asyncio"); if (!asyncio) uwsgi_pyexit; diff --git a/uwsgi.h b/uwsgi.h index 4604a8b4..27b534d6 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -3071,6 +3071,7 @@ struct wsgi_request *find_first_accepting_wsgi_req(void); struct wsgi_request *find_wsgi_req_by_fd(int); struct wsgi_request *find_wsgi_req_by_id(int); void async_schedule_to_req_green(void); +void async_schedule_to_req(void); int async_add_fd_write(struct wsgi_request *, int, int); int async_add_fd_read(struct wsgi_request *, int, int); diff --git a/uwsgidecorators.py b/uwsgidecorators.py index e1fa71b7..659af7a1 100644 --- a/uwsgidecorators.py +++ b/uwsgidecorators.py @@ -18,6 +18,29 @@ mule_functions = {} postfork_chain = [] +# Python3 compatibility +def _encode1(val): + if sys.version_info >= (3, 0) and isinstance(val, str): + return val.encode('utf-8') + else: + return val + + +def _decode1(val): + if sys.version_info >= (3, 0) and isinstance(val, bytes): + return val.decode('utf-8') + else: + return val + + +def _encode_to_spooler(vars): + return dict((_encode1(K), _encode1(V)) for (K, V) in vars.items()) + + +def _decode_from_spooler(vars): + return dict((_decode1(K), _decode1(V)) for (K, V) in vars.items()) + + def get_free_signal(): for signum in range(0, 256): if not uwsgi.signal_registered(signum): @@ -27,6 +50,7 @@ def get_free_signal(): def manage_spool_request(vars): + vars = _decode_from_spooler(vars) f = spooler_functions[vars['ud_spool_func']] if 'args' in vars: args = pickle.loads(vars.pop('args')) @@ -79,8 +103,9 @@ class _spoolraw(object): if key in kwargs: spooler_args.update({key: kwargs.pop(key)}) arguments.update(spooler_args) - arguments.update({'args': pickle.dumps(args), 'kwargs': pickle.dumps(kwargs)}) - return uwsgi.spool(arguments) + arguments.update( + {'args': pickle.dumps(args), 'kwargs': pickle.dumps(kwargs)}) + return uwsgi.spool(_encode_to_spooler(arguments)) # For backward compatibility (uWSGI < 1.9.13) def spool(self, *args, **kwargs):