mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-07 14:11:46 +00:00
added --wsgi-env-behaviour for choosing the WSGI environ allocator/destroyer policy
This commit is contained in:
@@ -128,6 +128,8 @@ struct uwsgi_option uwsgi_python_options[] = {
|
||||
{"py-auto-reload-ignore", required_argument, 0, "ignore the specified module during auto-reload scan (can be specified multiple times)", uwsgi_opt_add_string_list, &up.auto_reload_ignore, UWSGI_OPT_THREADS|UWSGI_OPT_MASTER},
|
||||
#endif
|
||||
|
||||
{"wsgi-env-behaviour", required_argument, 0, "set the strategy for allocating/deallocating the WSGI env", uwsgi_opt_set_str, &up.wsgi_env_behaviour, 0},
|
||||
{"wsgi-env-behavior", required_argument, 0, "set the strategy for allocating/deallocating the WSGI env", uwsgi_opt_set_str, &up.wsgi_env_behaviour, 0},
|
||||
{"start_response-nodelay", no_argument, 0, "send WSGI http headers as soon as possible (PEP violation)", uwsgi_opt_true, &up.start_response_nodelay, 0},
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
@@ -947,6 +949,44 @@ void uwsgi_python_spooler_init(void) {
|
||||
|
||||
}
|
||||
|
||||
// this is the default (fake) allocator for WSGI's env
|
||||
// the dictionary is created on app loading (one for each async core/thread) and reused (clearing it after each request, constantly)
|
||||
//
|
||||
// from a python-programmer point of view it is a hack/cheat but it does not violate the WSGI standard
|
||||
// and it is a bit faster than the "holy" allocator
|
||||
void *uwsgi_python_create_env_cheat(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
#ifdef UWSGI_ASYNC
|
||||
Py_INCREF((PyObject *)wi->environ[wsgi_req->async_id]);
|
||||
return wi->environ[wsgi_req->async_id];
|
||||
#else
|
||||
Py_INCREF((PyObject *)wi->environ);
|
||||
return wi->environ;
|
||||
#endif
|
||||
}
|
||||
|
||||
void uwsgi_python_destroy_env_cheat(struct wsgi_request *wsgi_req) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
|
||||
// this is the "holy" allocator for WSGI's env
|
||||
// Armin Ronacher told me this is what most of python programmers expect
|
||||
// I cannot speak for that as i am a perl guy, and i expect only black-magic things :P
|
||||
//
|
||||
// this should be the default one, but changing default behaviours (even if they are wrong)
|
||||
// always make my customers going berserk...
|
||||
//
|
||||
// it is only slightly (better: irrelevant) slower, so no fear in enabling it...
|
||||
|
||||
|
||||
void *uwsgi_python_create_env_holy(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
return PyDict_New();
|
||||
}
|
||||
|
||||
void uwsgi_python_destroy_env_holy(struct wsgi_request *wsgi_req) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_environ);
|
||||
}
|
||||
|
||||
|
||||
// this hook will be executed by master (or worker1 when master is not requested, so COW is in place)
|
||||
void uwsgi_python_preinit_apps() {
|
||||
|
||||
@@ -969,6 +1009,19 @@ void uwsgi_python_preinit_apps() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!up.wsgi_env_behaviour) {
|
||||
up.wsgi_env_create = uwsgi_python_create_env_cheat;
|
||||
up.wsgi_env_destroy = uwsgi_python_destroy_env_cheat;
|
||||
}
|
||||
else if (!strcmp(up.wsgi_env_behaviour, "holy")) {
|
||||
up.wsgi_env_create = uwsgi_python_create_env_holy;
|
||||
up.wsgi_env_destroy = uwsgi_python_destroy_env_holy;
|
||||
}
|
||||
else if (!strcmp(up.wsgi_env_behaviour, "cheat")) {
|
||||
up.wsgi_env_create = uwsgi_python_create_env_cheat;
|
||||
up.wsgi_env_destroy = uwsgi_python_destroy_env_cheat;
|
||||
}
|
||||
|
||||
init_uwsgi_vars();
|
||||
|
||||
// load shared imports
|
||||
|
||||
@@ -168,6 +168,11 @@ struct uwsgi_python {
|
||||
PyObject *embedded_dict;
|
||||
PyObject *embedded_args;
|
||||
|
||||
char *wsgi_env_behaviour;
|
||||
|
||||
void *(*wsgi_env_create)(struct wsgi_request *, struct uwsgi_app *);
|
||||
void (*wsgi_env_destroy)(struct wsgi_request *);
|
||||
|
||||
|
||||
int pep3333_input;
|
||||
|
||||
|
||||
@@ -439,20 +439,19 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
wsgi_req->async_environ = wi->environ[wsgi_req->async_id];
|
||||
wsgi_req->async_args = wi->args[wsgi_req->async_id];
|
||||
#else
|
||||
wsgi_req->async_environ = wi->environ;
|
||||
wsgi_req->async_args = wi->args;
|
||||
#endif
|
||||
|
||||
UWSGI_GET_GIL
|
||||
|
||||
// no fear of race conditions for this counter as it is already protected by the GIL
|
||||
wi->requests++;
|
||||
|
||||
Py_INCREF((PyObject *)wsgi_req->async_environ);
|
||||
#ifdef UWSGI_ASYNC
|
||||
wsgi_req->async_args = wi->args[wsgi_req->async_id];
|
||||
#else
|
||||
wsgi_req->async_args = wi->args;
|
||||
#endif
|
||||
|
||||
// create WSGI environ
|
||||
wsgi_req->async_environ = up.wsgi_env_create(wsgi_req, wi);
|
||||
|
||||
wsgi_req->async_result = wi->request_subhandler(wsgi_req, wi);
|
||||
|
||||
@@ -515,7 +514,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
up.wsgi_env_destroy(wsgi_req);
|
||||
}
|
||||
|
||||
UWSGI_RELEASE_GIL
|
||||
|
||||
Reference in New Issue
Block a user