summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2017-07-16 00:13:37 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2017-07-23 19:02:30 -0400
commitd66cbe9577ac092163babe6b816205fd14f1bc5a (patch)
tree9da17c0f2ad8d67a6fbbcc9af07d8d36f3a43d55
parent1836309209e1bc4268df02b7aaf06d2e89329581 (diff)
downloadlighttpd1.4-d66cbe9577ac092163babe6b816205fd14f1bc5a.tar.gz
lighttpd1.4-d66cbe9577ac092163babe6b816205fd14f1bc5a.zip
[core] adaptive spawning for socket backend procs (fixes #1162)
*experimental* enable adaptive spawning for socket backend processes new feature will allow "min-procs" => "0" and will spawn a backend upon receipt of a request, if no backends are currently running. This may be useful on resource-limited systems where there is a seldom-used resource-intensive backend, such as home router configuration web pages. The first request may be slower as the backend is starting up, but then subsequent requests within "idle-timeout" will hit the (temporarily) persistent backend for faster responses. x-ref: "Adaptive spawning with min-procs=>0" https://redmine.lighttpd.net/issues/1162
-rw-r--r--src/gw_backend.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/gw_backend.c b/src/gw_backend.c
index c74841e7..7b67f9a5 100644
--- a/src/gw_backend.c
+++ b/src/gw_backend.c
@@ -228,6 +228,7 @@ static int gw_extension_insert(gw_exts *ext, buffer *key, gw_host *fh) {
static void gw_proc_connect_success(server *srv, gw_host *host, gw_proc *proc, int debug) {
gw_proc_tag_inc(srv, host, proc, CONST_STR_LEN(".connected"));
+ proc->last_used = srv->cur_ts;
if (debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
@@ -912,6 +913,16 @@ static gw_host * gw_host_get(server *srv, connection *con, gw_extension *extensi
}
return host;
+ } else if (0 == srv->srvconf.max_worker) {
+ /* special-case adaptive spawning and 0 == host->min_procs */
+ for (k = 0; k < extension->used; ++k) {
+ host = extension->hosts[k];
+ if (0 == host->min_procs && 0 == host->num_procs
+ && !buffer_string_is_empty(host->bin_path)) {
+ gw_proc_spawn(srv, host, debug);
+ if (host->num_procs) return host;
+ }
+ }
}
/* all hosts are down */
@@ -1214,7 +1225,7 @@ int gw_set_defaults_backend(server *srv, gw_plugin_data *p, data_unset *du, size
{ "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
{ "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
- { "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */
+ { "min-procs", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
{ "max-procs", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
{ "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
{ "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
@@ -1402,11 +1413,15 @@ int gw_set_defaults_backend(server *srv, gw_plugin_data *p, data_unset *du, size
host->args.ptr[3] = NULL;
}
- /* HACK: just to make sure the adaptive spawing is disabled */
- host->min_procs = host->max_procs;
-
if (host->min_procs > host->max_procs)
- host->max_procs = host->min_procs;
+ host->min_procs = host->max_procs;
+ if (host->min_procs!= host->max_procs
+ && 0 != srv->srvconf.max_worker) {
+ host->min_procs = host->max_procs;
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "adaptive backend spawning disabled "
+ "(server.max_worker is non-zero)");
+ }
if (host->max_load_per_proc < 1)
host->max_load_per_proc = 0;
@@ -1420,7 +1435,7 @@ int gw_set_defaults_backend(server *srv, gw_plugin_data *p, data_unset *du, size
"\n\tmax-procs:", host->max_procs);
}
- for (size_t pno = 0; pno < host->max_procs; ++pno) {
+ for (size_t pno = 0; pno < host->min_procs; ++pno) {
gw_proc *proc = gw_proc_init();
proc->id = host->num_procs++;
host->max_id++;
@@ -1975,6 +1990,7 @@ static handler_t gw_recv_response(server *srv, gw_handler_ctx *hctx) {
physpath = con->physical.path;
}
+ proc->last_used = srv->cur_ts;
gw_backend_close(srv, hctx);
handler_ctx_clear(hctx);
@@ -2358,7 +2374,7 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
gw_proc *proc;
time_t idle_timestamp;
- unsigned long sum_load = 0;
+ int overload = 1;
for (proc = host->first; proc; proc = proc->next) {
gw_proc_waitpid(srv, host, proc);
@@ -2366,14 +2382,18 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
gw_restart_dead_procs(srv, host, debug);
+ /* check if adaptive spawning enabled */
+ if (host->min_procs == host->max_procs) return;
if (buffer_string_is_empty(host->bin_path)) return;
for (proc = host->first; proc; proc = proc->next) {
- sum_load += proc->load;
+ if (proc->load <= host->max_load_per_proc) {
+ overload = 0;
+ break;
+ }
}
- if (host->num_procs && host->num_procs < host->max_procs
- && (sum_load / host->num_procs) > host->max_load_per_proc) {
+ if (overload && host->num_procs && host->num_procs < host->max_procs) {
/* overload, spawn new child */
if (debug) {
log_error_write(srv, __FILE__, __LINE__, "s",