new loader refactoring

This commit is contained in:
roberto@sirius
2010-09-30 18:13:40 +02:00
parent 42c5b356f5
commit 551152ade9
6 changed files with 264 additions and 147 deletions
+2
View File
@@ -0,0 +1,2 @@
all:
python3.2 uwsgiconfig.py --build
+102 -19
View File
@@ -18,8 +18,28 @@ PyMethodDef uwsgi_eventfd_read_method[] = { {"uwsgi_eventfd_read", py_eventfd_re
PyMethodDef uwsgi_eventfd_write_method[] = { {"uwsgi_eventfd_write", py_eventfd_write, METH_VARARGS, ""}};
#endif
void init_uwsgi_py_interpreter(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
// Initialize a new environment for the new interpreter
int init_uwsgi_app(struct uwsgi_server *uwsgi, PyObject *my_callable) {
uwsgi_log("setting new interpreter\n");
wi->interpreter = Py_NewInterpreter();
if (!wi->interpreter) {
uwsgi_log( "unable to initialize the new python interpreter\n");
exit(1);
}
PyThreadState_Swap(wi->interpreter);
init_pyargv(uwsgi);
#ifdef UWSGI_EMBEDDED
// we need to inizialize an embedded module for every interpreter
init_uwsgi_embedded_module();
#endif
init_uwsgi_vars();
}
int init_uwsgi_app(int loader, char *arg1, struct uwsgi_server *uwsgi, PyObject *my_callable, int new_interpreter) {
PyObject *wsgi_module, *wsgi_dict;
PyObject *zero;
@@ -77,30 +97,28 @@ int init_uwsgi_app(struct uwsgi_server *uwsgi, PyObject *my_callable) {
uwsgi_error("chdir()");
}
}
// Initialize a new environment for the new interpreter
if (uwsgi->single_interpreter == 0) {
wi->interpreter = Py_NewInterpreter();
if (!wi->interpreter) {
uwsgi_log( "unable to initialize the new python interpreter\n");
exit(1);
}
PyThreadState_Swap(wi->interpreter);
init_pyargv(uwsgi);
if (new_interpreter) {
uwsgi_log("setting new interpreter\n");
wi->interpreter = Py_NewInterpreter();
if (!wi->interpreter) {
uwsgi_log( "unable to initialize the new python interpreter\n");
exit(1);
}
PyThreadState_Swap(wi->interpreter);
init_pyargv(uwsgi);
#ifdef UWSGI_EMBEDDED
// we need to inizialize an embedded module for every interpreter
init_uwsgi_embedded_module();
// we need to inizialize an embedded module for every interpreter
init_uwsgi_embedded_module();
#endif
init_uwsgi_vars();
uwsgi_log( "interpreter for app %d initialized.\n", id);
init_uwsgi_vars();
}
wi->wsgi_callable = uwsgi->loaders[loader](arg1)
if (my_callable) {
wi->wsgi_callable = my_callable;
@@ -260,7 +278,7 @@ int init_uwsgi_app(struct uwsgi_server *uwsgi, PyObject *my_callable) {
#endif
}
if (uwsgi->single_interpreter == 0) {
if (new_interpreter) {
PyThreadState_Swap(uwsgi->main_thread);
}
@@ -286,10 +304,75 @@ int init_uwsgi_app(struct uwsgi_server *uwsgi, PyObject *my_callable) {
doh:
PyErr_Print();
if (uwsgi->single_interpreter == 0) {
if (new_interpreter) {
Py_EndInterpreter(wi->interpreter);
PyThreadState_Swap(uwsgi->main_thread);
}
return -1;
}
/* trying to emulate Graham's mod_wsgi, this will allows easy and fast migrations */
PyObject *uwsgi_file_loader(char *filename) {
FILE *wsgifile;
struct _node *wsgi_file_node = NULL;
PyObject *wsgi_compiled_node, *wsgi_file_module, *wsgi_file_dict;
PyObject *wsgi_file_callable;
int ret;
wsgifile = fopen(filename, "r");
if (!wsgifile) {
uwsgi_error("fopen()");
exit(1);
}
wsgi_file_node = PyParser_SimpleParseFile(wsgifile, filename, Py_file_input);
if (!wsgi_file_node) {
PyErr_Print();
uwsgi_log( "failed to parse file %s\n", filename);
exit(1);
}
fclose(wsgifile);
wsgi_compiled_node = (PyObject *) PyNode_Compile(wsgi_file_node, filename);
if (!wsgi_compiled_node) {
PyErr_Print();
uwsgi_log( "failed to compile wsgi file %s\n", filename);
exit(1);
}
wsgi_file_module = PyImport_ExecCodeModule("uwsgi_wsgi_file", wsgi_compiled_node);
if (!wsgi_file_module) {
PyErr_Print();
exit(1);
}
Py_DECREF(wsgi_compiled_node);
wsgi_file_dict = PyModule_GetDict(wsgi_file_module);
if (!wsgi_file_dict) {
PyErr_Print();
exit(1);
}
wsgi_file_callable = PyDict_GetItemString(wsgi_file_dict, "application");
if (!wsgi_file_callable) {
PyErr_Print();
uwsgi_log( "unable to find \"application\" callable in file %s\n", filename);
exit(1);
}
if (!PyFunction_Check(wsgi_file_callable) && !PyCallable_Check(wsgi_file_callable)) {
uwsgi_log( "\"application\" must be a callable object in file %s\n", filename);
exit(1);
}
return wsgi_file_callable;
}
-16
View File
@@ -471,22 +471,6 @@ void sanitize_args(struct uwsgi_server *uwsgi) {
#endif
#endif
if (uwsgi->wsgi_config || uwsgi->wsgi_file || uwsgi->eval) {
uwsgi->single_interpreter = 1 ;
}
#ifdef UWSGI_INI
if (uwsgi->ini) {
uwsgi->single_interpreter = 1 ;
}
#endif
#ifdef UWSGI_PASTE
if (uwsgi->paste) {
uwsgi->single_interpreter = 1 ;
}
#endif
if (uwsgi->shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
if (!uwsgi->post_buffering) {
uwsgi_log(" *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** \n");
+73 -105
View File
@@ -557,7 +557,7 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.ini = lazy;
}
else if (!strcmp(lazy+strlen(lazy)-5, ".wsgi")) {
uwsgi.wsgi_file = lazy;
uwsgi.file_config = lazy;
}
else {
uwsgi.wsgi_config = lazy;
@@ -1227,28 +1227,43 @@ int main(int argc, char *argv[], char *envp[]) {
}
#endif
// setup app loaders
#ifdef UWSGI_MINTERPRETERS
uwsgi.loaders[LOADER_DYNAMIC] = uwsgi_dynamic_loader;
#endif
uwsgi.loaders[LOADER_UWSGI] = uwsgi_uwsgi_loader;
uwsgi.loaders[LOADER_FILE] = uwsgi_file_loader;
#ifdef UWSGI_XML
uwsgi.loaders[LOADER_XML] = uwsgi_xml_loader;
#endif
#ifdef UWSGI_PASTE
uwsgi.loaders[LOADER_PASTE] = uwsgi_paste_loader;
#endif
uwsgi.loaders[LOADER_EVAL] = uwsgi_eval_loader;
if (uwsgi.wsgi_config != NULL) {
uwsgi_wsgi_config(NULL);
init_uwsgi_app(LOADER_UWSGI, uwsgi.wsgi_config, &uwsgi, uwsgi.wsgi_req, 0);
}
else if (uwsgi.file_config != NULL) {
uwsgi_wsgi_config(uwsgi.file_config);
}
else if (uwsgi.wsgi_file != NULL) {
uwsgi_wsgi_file_config();
init_uwsgi_app(LOADER_FILE, uwsgi.file_config, &uwsgi, uwsgi.wsgi_req, 0);
}
#ifdef UWSGI_PASTE
else if (uwsgi.paste != NULL) {
uwsgi_paste_config();
init_uwsgi_app(LOADER_PASTE, uwsgi.paste, &uwsgi, uwsgi.wsgi_req, 0);
}
#endif
else if (uwsgi.eval != NULL) {
uwsgi_eval_config(uwsgi.eval);
init_uwsgi_app(LOADER_EVAL, uwsgi.eval, &uwsgi, uwsgi.wsgi_req, 0);
}
// parse xml anyway
#ifdef UWSGI_XML
if (uwsgi.xml_round2 && uwsgi.xml_config != NULL) {
uwsgi_xml_config(uwsgi.wsgi_req, NULL);
init_uwsgi_app(LOADER_XML, uwsgi.xml_config, &uwsgi, uwsgi.wsgi_req, 0);
}
#endif
@@ -1595,6 +1610,8 @@ void init_uwsgi_vars() {
PyObject *site_module;
#endif
uwsgi_log("AAAAAAA\n");
/* add cwd to pythonpath */
pysys = PyImport_ImportModule("sys");
if (!pysys) {
@@ -1612,6 +1629,8 @@ void init_uwsgi_vars() {
// simulate a pythonhome directive
if (uwsgi.wsgi_req->pyhome_len > 0) {
uwsgi_log("TEST000\n");
PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->pyhome, uwsgi.wsgi_req->pyhome_len) ;
#ifdef UWSGI_DEBUG
@@ -1657,13 +1676,11 @@ void init_uwsgi_vars() {
}
#ifdef UWSGI_PASTE
void uwsgi_paste_config() {
void uwsgi_paste_config(char *paste) {
PyObject *paste_module, *paste_dict, *paste_loadapp;
PyObject *paste_arg, *paste_app;
uwsgi.single_interpreter = 1;
uwsgi_log( "Loading paste environment: %s\n", uwsgi.paste);
uwsgi_log( "Loading paste environment: %s\n", paste);
paste_module = PyImport_ImportModule("paste.deploy");
if (!paste_module) {
PyErr_Print();
@@ -1688,7 +1705,7 @@ void uwsgi_paste_config() {
exit(1);
}
if (PyTuple_SetItem(paste_arg, 0, PyString_FromString(uwsgi.paste))) {
if (PyTuple_SetItem(paste_arg, 0, PyString_FromString(paste))) {
PyErr_Print();
exit(1);
}
@@ -1708,12 +1725,12 @@ void uwsgi_eval_config(char *code) {
int ret;
PyObject *wsgi_eval_dict, *wsgi_eval_module, *wsgi_eval_callable;
PyObject *wsgi_eval_module, *wsgi_eval_callable;
struct _node *wsgi_eval_node = NULL;
PyObject *wsgi_compiled_node ;
uwsgi.single_interpreter = 1;
uwsgi_log("parsing code\n");
wsgi_eval_node = PyParser_SimpleParseString(code, Py_file_input);
if (!wsgi_eval_node) {
@@ -1740,38 +1757,34 @@ void uwsgi_eval_config(char *code) {
Py_DECREF(wsgi_compiled_node);
wsgi_eval_dict = PyModule_GetDict(wsgi_eval_module);
if (!wsgi_eval_dict) {
uwsgi.pyloader_dict = PyModule_GetDict(wsgi_eval_module);
if (!uwsgi.pyloader_dict) {
PyErr_Print();
exit(1);
}
if (uwsgi.callable) {
wsgi_eval_callable = PyDict_GetItemString(wsgi_eval_dict, uwsgi.callable);
wsgi_eval_callable = PyDict_GetItemString(uwsgi.pyloader_dict, uwsgi.callable);
}
else {
wsgi_eval_callable = PyDict_GetItemString(wsgi_eval_dict, "application");
wsgi_eval_callable = PyDict_GetItemString(uwsgi.pyloader_dict, "application");
}
if (!wsgi_eval_callable) {
PyErr_Print();
uwsgi_log( "unable to find wsgi callable in your code\n");
exit(1);
}
if (wsgi_eval_callable) {
uwsgi_log( "found the \"%s\" callable\n", uwsgi.callable);
if (!PyFunction_Check(wsgi_eval_callable) && !PyCallable_Check(wsgi_eval_callable)) {
uwsgi_log( "you must define a callable object in your code\n");
exit(1);
}
ret = init_uwsgi_app(&uwsgi, wsgi_eval_callable);
}
if (!PyFunction_Check(wsgi_eval_callable) && !PyCallable_Check(wsgi_eval_callable)) {
uwsgi_log( "you must define a callable object in your code\n");
exit(1);
}
ret = init_uwsgi_app(&uwsgi, wsgi_eval_callable);
uwsgi_log("oops\n");
}
/* trying to emulate Graham's mod_wsgi, this will allows easy and fast migrations */
void uwsgi_wsgi_file_config() {
void uwsgi_file_config(char *filename) {
FILE *wsgifile;
struct _node *wsgi_file_node = NULL;
@@ -1779,28 +1792,26 @@ void uwsgi_wsgi_file_config() {
PyObject *wsgi_file_callable;
int ret;
uwsgi.single_interpreter = 1;
wsgifile = fopen(uwsgi.wsgi_file, "r");
wsgifile = fopen(filename, "r");
if (!wsgifile) {
uwsgi_error("fopen()");
exit(1);
}
wsgi_file_node = PyParser_SimpleParseFile(wsgifile, uwsgi.wsgi_file, Py_file_input);
wsgi_file_node = PyParser_SimpleParseFile(wsgifile, filename, Py_file_input);
if (!wsgi_file_node) {
PyErr_Print();
uwsgi_log( "failed to parse wsgi file %s\n", uwsgi.wsgi_file);
uwsgi_log( "failed to parse file %s\n", filename);
exit(1);
}
fclose(wsgifile);
wsgi_compiled_node = (PyObject *) PyNode_Compile(wsgi_file_node, uwsgi.wsgi_file);
wsgi_compiled_node = (PyObject *) PyNode_Compile(wsgi_file_node, filename);
if (!wsgi_compiled_node) {
PyErr_Print();
uwsgi_log( "failed to compile wsgi file %s\n", uwsgi.wsgi_file);
uwsgi_log( "failed to compile wsgi file %s\n", filename);
exit(1);
}
@@ -1822,12 +1833,12 @@ void uwsgi_wsgi_file_config() {
wsgi_file_callable = PyDict_GetItemString(wsgi_file_dict, "application");
if (!wsgi_file_callable) {
PyErr_Print();
uwsgi_log( "unable to find \"application\" callable in wsgi file %s\n", uwsgi.wsgi_file);
uwsgi_log( "unable to find \"application\" callable in file %s\n", filename);
exit(1);
}
if (!PyFunction_Check(wsgi_file_callable) && !PyCallable_Check(wsgi_file_callable)) {
uwsgi_log( "\"application\" must be a callable object in wsgi file %s\n", uwsgi.wsgi_file);
uwsgi_log( "\"application\" must be a callable object in file %s\n", filename);
exit(1);
}
@@ -1837,7 +1848,7 @@ void uwsgi_wsgi_file_config() {
}
void uwsgi_wsgi_config(char *filename) {
void uwsgi_wsgi_config(char *module) {
PyObject *wsgi_module, *wsgi_dict;
#ifdef UWSGI_EMBEDDED
@@ -1848,75 +1859,34 @@ void uwsgi_wsgi_config(char *filename) {
int ret;
Py_ssize_t i;
PyObject *app_mnt, *app_app = NULL;
FILE *uwsgifile;
char *quick_callable = NULL;
PyObject *uwsgi_compiled_node;
struct _node *uwsgi_file_node;
PyObject *tmp_callable;
uwsgi.single_interpreter = 1;
char *the_module = module ;
if (filename) {
if (!the_module) {
the_module = uwsgi.wsgi_config;
}
if (uwsgi.callable) {
quick_callable = uwsgi.callable ;
}
uwsgifile = fopen(filename, "r");
if (!uwsgifile) {
uwsgi_error("fopen()");
exit(1);
}
uwsgi_file_node = PyParser_SimpleParseFile(uwsgifile, filename, Py_file_input);
if (!uwsgi_file_node) {
PyErr_Print();
uwsgi_log( "failed to parse wsgi file %s\n", filename);
exit(1);
}
fclose(uwsgifile);
uwsgi_compiled_node = (PyObject *) PyNode_Compile(uwsgi_file_node, filename);
if (!uwsgi_compiled_node) {
PyErr_Print();
uwsgi_log( "failed to compile wsgi file %s\n", filename);
exit(1);
}
wsgi_module = PyImport_ExecCodeModule("uwsgi_config_file", uwsgi_compiled_node);
if (!wsgi_module) {
PyErr_Print();
exit(1);
}
Py_DECREF(uwsgi_compiled_node);
uwsgi.wsgi_config = "uwsgi_config_file";
if (uwsgi.callable) {
quick_callable = uwsgi.callable ;
}
else {
if (uwsgi.callable) {
quick_callable = uwsgi.callable ;
}
else {
quick_callable = strchr(uwsgi.wsgi_config, ':');
if (quick_callable) {
quick_callable[0] = 0 ;
quick_callable++;
}
}
wsgi_module = PyImport_ImportModule(uwsgi.wsgi_config);
if (!wsgi_module) {
PyErr_Print();
exit(1);
quick_callable = strchr(the_module, ':');
if (quick_callable) {
quick_callable[0] = 0 ;
quick_callable++;
}
}
wsgi_module = PyImport_ImportModule(the_module);
if (!wsgi_module) {
PyErr_Print();
exit(1);
}
wsgi_dict = PyModule_GetDict(wsgi_module);
if (!wsgi_dict) {
@@ -1926,7 +1896,7 @@ void uwsgi_wsgi_config(char *filename) {
if (!quick_callable) {
uwsgi_log( "...getting the applications list from the '%s' module...\n", uwsgi.wsgi_config);
uwsgi_log( "...getting the applications list from the '%s' module...\n", the_module);
#ifdef UWSGI_EMBEDDED
uwsgi_module = PyImport_ImportModule("uwsgi");
@@ -2388,8 +2358,6 @@ void manage_opt(int i, char *optarg) {
uwsgi.binary_path = optarg;
break;
case LONG_ARGS_WSGI_FILE:
uwsgi.wsgi_file = optarg;
break;
case LONG_ARGS_FILE_CONFIG:
uwsgi.file_config = optarg;
break;
+15 -4
View File
@@ -665,7 +665,6 @@ struct uwsgi_server {
#ifdef UWSGI_PASTE
char *paste;
#endif
char *wsgi_file;
int single_interpreter;
int py_optimize;
@@ -755,6 +754,7 @@ struct uwsgi_server {
time_t respawn_delta;
PyObject *pyloader_dict;
};
struct uwsgi_cluster_node {
@@ -882,9 +882,9 @@ void uwsgi_xml_config(struct wsgi_request *, struct option *);
void uwsgi_wsgi_config(char *);
#ifdef UWSGI_PASTE
void uwsgi_paste_config(void);
void uwsgi_paste_config(char *);
#endif
void uwsgi_wsgi_file_config(void);
void uwsgi_file_config(char *);
void uwsgi_eval_config(char *);
void internal_server_error(int, char *);
@@ -915,7 +915,7 @@ uint32_t uwsgi_swap32(uint32_t);
uint64_t uwsgi_swap64(uint64_t);
#endif
int init_uwsgi_app(struct uwsgi_server *, PyObject *);
int init_uwsgi_app(struct uwsgi_server *, PyObject *, int);
PyObject *uwsgi_send_message(const char *, int, uint8_t, uint8_t, char *, int, int);
@@ -1201,3 +1201,14 @@ void master_loop(struct uwsgi_server *, char **, char **);
int find_worker_id(pid_t);
void init_uwsgi_py_interpreter(struct uwsgi_server *, struct wsgi_request *);
#define LOADER_DYNAMIC 0
#define LOADER_UWSGI 1
#define LOADER_FILE 2
#define LOADER_XML 3
#define LOADER_PASTE 4
#define LOADER_EVAL 5
#define LOADER_MAX 6
+72 -3
View File
@@ -167,14 +167,83 @@ next:
for (node2 = node->children; node2; node2 = node2->next) {
if (node2->type == XML_ELEMENT_NODE) {
if (!strcmp((char *) node2->name, "script")) {
if (!strcmp((char *) node2->name, "pyhome")) {
if (!node2->children) {
uwsgi_log( "no wsgi script defined. skip.\n");
uwsgi_log( "no virtualenv defined. skip.\n");
continue;
}
if (node2->children->content == NULL) {
uwsgi_log( "no virtualenv defined. skip.\n");
continue;
}
wsgi_req->pyhome = (char *) node2->children->content;
wsgi_req->pyhome_len = strlen((char *) node2->children->content);
uwsgi_log("fatto\n");
}
else if (!strcmp((char *) node2->name, "callable")) {
if (!uwsgi.pyloader_dict) {
uwsgi_log( "no module loaded in memory. skip.\n");
continue;
}
if (!node2->children) {
uwsgi_log( "no callable defined. skip.\n");
continue;
}
if (node2->children->content == NULL) {
uwsgi_log( "no callable defined. skip.\n");
continue;
}
//init_uwsgi_app(&uwsgi, PyDict_GetItemString(uwsgi.pyloader_dict, (char *) node2->children->content) );
}
else if (!strcmp((char *) node2->name, "eval")) {
if (!node2->children) {
uwsgi_log( "no code defined. skip.\n");
continue;
}
if (node2->children->content == NULL) {
uwsgi_log( "no code defined. skip.\n");
continue;
}
uwsgi_eval_config((char *)node2->children->content);
}
else if (!strcmp((char *) node2->name, "file")) {
if (!node2->children) {
uwsgi_log( "no file defined. skip.\n");
continue;
}
if (node2->children->content == NULL) {
uwsgi_log( "no file defined. skip.\n");
continue;
}
uwsgi_file_config((char *)node2->children->content);
}
else if (!strcmp((char *) node2->name, "module")) {
if (!node2->children) {
uwsgi_log( "no module defined. skip.\n");
continue;
}
if (node2->children->content == NULL) {
uwsgi_log( "no module defined. skip.\n");
continue;
}
uwsgi_wsgi_config((char *)node2->children->content);
}
else if (!strcmp((char *) node2->name, "script")) {
if (!node2->children) {
uwsgi_log( "no script defined. skip.\n");
continue;
}
xml_uwsgi_script = node2->children->content;
if (xml_uwsgi_script == NULL) {
uwsgi_log( "no wsgi script defined. skip.\n");
uwsgi_log( "no script defined. skip.\n");
continue;
}
wsgi_req->wsgi_script = (char *) xml_uwsgi_script;