diff --git a/plugins/python/wsgi_headers.c b/plugins/python/wsgi_headers.c index 50b8ef79..7ba1c085 100644 --- a/plugins/python/wsgi_headers.c +++ b/plugins/python/wsgi_headers.c @@ -14,22 +14,36 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) { PyObject *h_key, *h_value; int i, j; struct uwsgi_header uh; + PyObject *exc_info = NULL; struct wsgi_request *wsgi_req = current_wsgi_req(); int base = 0; - int shift = 0; - // use writev() + // this must be done before headers management + if (PyTuple_Size(args) > 2) { + exc_info = PyTuple_GetItem(args, 2); + if (exc_info && exc_info != Py_None) { + PyObject *exc_type = PyTuple_GetItem(exc_info, 0); + PyObject *exc_val = PyTuple_GetItem(exc_info, 1); + PyObject *exc_tb = PyTuple_GetItem(exc_info, 2); - // is a Web3 response ? - /* - if (PyTuple_Size(args) == 3) { - shift = 0; - } - */ + if (!exc_type || !exc_val || !exc_tb) { + PyErr_Print(); + goto clear; + } - head = PyTuple_GetItem(args, 0+shift); + Py_INCREF(exc_type); + Py_INCREF(exc_val); + Py_INCREF(exc_tb); + // in this way, error will be reported to the log + PyErr_Restore(exc_type, exc_val, exc_tb); + + goto clear; + } + } + + head = PyTuple_GetItem(args, 0); if (!head) { goto clear; } @@ -93,19 +107,16 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) { uh.pktsize += wsgi_req->hvec[2].iov_len; } + headers = PyTuple_GetItem(args, 1); + if (!headers) goto clear; + - headers = PyTuple_GetItem(args, 1+shift); - if (!headers) { - goto clear; - } if (!PyList_Check(headers)) { uwsgi_log( "http headers must be in a python list\n"); goto clear; } wsgi_req->header_cnt = PyList_Size(headers); - - if (wsgi_req->header_cnt > uwsgi.max_vars) { wsgi_req->header_cnt = uwsgi.max_vars; } @@ -174,7 +185,6 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) { //uwsgi_log("%d %p\n", wsgi_req->poll.fd, up.wsgi_writeout); Py_INCREF(up.wsgi_writeout); - return up.wsgi_writeout; clear: diff --git a/utils.c b/utils.c index 745d7348..281fb377 100644 --- a/utils.c +++ b/utils.c @@ -408,7 +408,7 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { // get memory usage - if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1) + if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.reload_on_as || uwsgi.reload_on_rss) get_memusage(); @@ -442,6 +442,14 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { goodbye_cruel_world(); } + if (uwsgi.reload_on_as && (int) (uwsgi.workers[uwsgi.mywid].vsz_size / 1024 / 1024) >= uwsgi.reload_on_as) { + goodbye_cruel_world(); + } + + if (uwsgi.reload_on_rss && (int) (uwsgi.workers[uwsgi.mywid].rss_size / 1024 / 1024) >= uwsgi.reload_on_rss) { + goodbye_cruel_world(); + } + } diff --git a/uwsgi.c b/uwsgi.c index fe15d6ae..53247dc4 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -102,6 +102,8 @@ static struct option long_base_options[] = { {"no-server", no_argument, &uwsgi.no_server, 1}, {"no-defer-accept", no_argument, &uwsgi.no_defer_accept, 1}, {"limit-as", required_argument, 0, LONG_ARGS_LIMIT_AS}, + {"reload-on-as", required_argument, 0, LONG_ARGS_RELOAD_ON_AS}, + {"reload-on-rss", required_argument, 0, LONG_ARGS_RELOAD_ON_RSS}, {"limit-post", required_argument, 0, LONG_ARGS_LIMIT_POST}, {"no-orphans", no_argument, &uwsgi.no_orphans, 1}, {"prio", required_argument, 0, LONG_ARGS_PRIO}, @@ -229,6 +231,7 @@ void end_me(int signum) void goodbye_cruel_world() { + uwsgi.workers[uwsgi.mywid].manage_next_request = 0; uwsgi_log("...The work of process %d is done. Seeya!\n", getpid()); exit(0); } @@ -2529,6 +2532,12 @@ end: case LONG_ARGS_LIMIT_POST: uwsgi.limit_post = (int) strtol(optarg, NULL, 10); return 1; + case LONG_ARGS_RELOAD_ON_AS: + uwsgi.reload_on_as = atoi(optarg); + return 1; + case LONG_ARGS_RELOAD_ON_RSS: + uwsgi.reload_on_rss = atoi(optarg); + return 1; case LONG_ARGS_PRIO: uwsgi.prio = (int) strtol(optarg, NULL, 10); return 1; diff --git a/uwsgi.h b/uwsgi.h index 9551d054..42e9d3bf 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -393,6 +393,8 @@ struct uwsgi_opt { #define LONG_ARGS_SHARED_SOCKET 17090 #define LONG_ARGS_STATIC_MAP 17091 #define LONG_ARGS_FILE_SERVE_MODE 17092 +#define LONG_ARGS_RELOAD_ON_AS 17093 +#define LONG_ARGS_RELOAD_ON_RSS 17094 #define UWSGI_OK 0 @@ -853,6 +855,9 @@ struct uwsgi_server { size_t limit_post; int prio; + int reload_on_as; + int reload_on_rss; + int grunt; char *binary_path;