diff --git a/gateway.c b/gateway.c index 6fc6242e..17be0808 100644 --- a/gateway.c +++ b/gateway.c @@ -122,6 +122,12 @@ void gateway_respawn(int id) { } ug->pid = gw_pid; - uwsgi_log( "respawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid); + ug->respawns++; + if (ug->respawns == 1) { + uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid); + } + else { + uwsgi_log( "respawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid); + } } diff --git a/plugins/fastrouter/fastrouter.c b/plugins/fastrouter/fastrouter.c index e1b84c18..3aa98850 100644 --- a/plugins/fastrouter/fastrouter.c +++ b/plugins/fastrouter/fastrouter.c @@ -19,6 +19,7 @@ #define LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER 150005 #define LONG_ARGS_FASTROUTER_TIMEOUT 150006 #define LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT 150007 +#define LONG_ARGS_FASTROUTER_USE_CODE_STRING 150008 #define FASTROUTER_STATUS_FREE 0 #define FASTROUTER_STATUS_CONNECTING 1 @@ -55,6 +56,10 @@ struct uwsgi_fastrouter { int socket_timeout; + uint8_t code_string_modifier1; + char *code_string_code; + char *code_string_function; + struct rb_root *timeouts; } ufr; @@ -90,6 +95,7 @@ struct option fastrouter_options[] = { {"fastrouter-use-cache", no_argument, &ufr.use_cache, 1}, {"fastrouter-use-pattern", required_argument, 0, LONG_ARGS_FASTROUTER_USE_PATTERN}, {"fastrouter-use-base", required_argument, 0, LONG_ARGS_FASTROUTER_USE_BASE}, + {"fastrouter-use-code-string", required_argument, 0, LONG_ARGS_FASTROUTER_USE_CODE_STRING}, {"fastrouter-events", required_argument, 0, LONG_ARGS_FASTROUTER_EVENTS}, {"fastrouter-subscription-server", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER}, {"fastrouter-subscription-slot", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT}, @@ -457,6 +463,19 @@ void fastrouter_loop() { fr_session->instance_address_len = tmp_socket_name_len; fr_session->instance_address = tmp_socket_name; } + else if (ufr.code_string_code && ufr.code_string_function) { + if (uwsgi.p[ufr.code_string_modifier1]->code_string) { + fr_session->instance_address = uwsgi.p[ufr.code_string_modifier1]->code_string("uwsgi_fastrouter", ufr.code_string_code, ufr.code_string_function, fr_session->hostname, fr_session->hostname_len); + if (fr_session->instance_address) { + fr_session->instance_address_len = strlen(fr_session->instance_address); + } + char *cs_mod = uwsgi_str_contains(fr_session->instance_address, fr_session->instance_address_len, ','); + if (cs_mod) { + fr_session->modifier1 = uwsgi_str_num(cs_mod+1, (fr_session->instance_address_len - (cs_mod - fr_session->instance_address))-1); + fr_session->instance_address_len = (cs_mod - fr_session->instance_address); + } + } + } // no address found if (!fr_session->instance_address_len) { @@ -627,9 +646,17 @@ int fastrouter_init() { if (!ufr.nevents) ufr.nevents = 64; - if (register_gateway("fastrouter", fastrouter_loop) == NULL) { - uwsgi_log("unable to register the fastrouter gateway\n"); - exit(1); + if (ufr.code_string_code && ufr.code_string_function) { + if (register_fat_gateway("fastrouter", fastrouter_loop) == NULL) { + uwsgi_log("unable to register the fastrouter gateway\n"); + exit(1); + } + } + else { + if (register_gateway("fastrouter", fastrouter_loop) == NULL) { + uwsgi_log("unable to register the fastrouter gateway\n"); + exit(1); + } } } @@ -638,6 +665,10 @@ int fastrouter_init() { int fastrouter_opt(int i, char *optarg) { + char *cs; + char *cs_code; + char *cs_func; + switch(i) { case LONG_ARGS_FASTROUTER: uwsgi_fastrouter_new_socket(generate_socket_name(optarg)); @@ -658,6 +689,24 @@ int fastrouter_opt(int i, char *optarg) { // optimization ufr.base_len = strlen(ufr.base); return 1; + case LONG_ARGS_FASTROUTER_USE_CODE_STRING: + cs = uwsgi_str(optarg); + cs_code = strchr(cs, ':'); + if (!cs_code) { + uwsgi_log("invalid code_string option\n"); + exit(1); + } + cs_code[0] = 0; + cs_func = strchr(cs_code+1, ':'); + if (!cs_func) { + uwsgi_log("invalid code_string option\n"); + exit(1); + } + cs_func[0] = 0; + ufr.code_string_modifier1 = atoi(cs); + ufr.code_string_code = cs_code+1; + ufr.code_string_function = cs_func+1; + return 1; case LONG_ARGS_FASTROUTER_TIMEOUT: ufr.socket_timeout = atoi(optarg); return -1; diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index ac99c152..ec510c07 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -1109,6 +1109,56 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) { } +char *uwsgi_python_code_string(char *id, char *code, char *function, char *key, uint16_t keylen) { + + PyObject *cs_module = NULL; + PyObject *cs_dict = NULL; + + UWSGI_GET_GIL; + + cs_module = PyImport_ImportModule(id); + if (!cs_module) { + PyErr_Clear(); + cs_module = uwsgi_pyimport_by_filename(id, code); + } + + if (!cs_module) { + UWSGI_RELEASE_GIL; + return NULL; + } + + cs_dict = PyModule_GetDict(cs_module); + if (!cs_dict) { + PyErr_Print(); + UWSGI_RELEASE_GIL; + return NULL; + } + + PyObject *func = PyDict_GetItemString(cs_dict, function); + if (!func) { + uwsgi_log("function %s not available in %s\n", function, code); + PyErr_Print(); + UWSGI_RELEASE_GIL; + return NULL; + } + + PyObject *args = PyTuple_New(1); + + PyTuple_SetItem(args, 0, PyString_FromStringAndSize(key, keylen)); + + PyObject *ret = python_call(func, args, 0, NULL); + Py_DECREF(args); + if (ret && PyString_Check(ret)) { + char *val = PyString_AsString(ret); + UWSGI_RELEASE_GIL; + return val; + } + + UWSGI_RELEASE_GIL; + return NULL; + +} + int uwsgi_python_signal_handler(uint8_t sig, void *handler) { UWSGI_GET_GIL; @@ -1125,7 +1175,7 @@ int uwsgi_python_signal_handler(uint8_t sig, void *handler) { PyTuple_SetItem(args, 0, PyInt_FromLong(sig)); ret = python_call(handler, args, 0, NULL); - + Py_DECREF(args); if (ret) { UWSGI_RELEASE_GIL; return 0; @@ -1310,6 +1360,8 @@ struct uwsgi_plugin python_plugin = { .spooler = uwsgi_python_spooler, + .code_string = uwsgi_python_code_string, + .help = uwsgi_python_help, }; diff --git a/utils.c b/utils.c index 12ed05d7..24346280 100644 --- a/utils.c +++ b/utils.c @@ -1073,6 +1073,17 @@ void uwsgi_log_verbose(const char *fmt, ...) { rlen = write(2, logpkt, rlen); } +char *uwsgi_str_contains(char *str, int slen, char what) { + + int i; + for(i=0;i