kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit b869041a142e1e1a1b590cebe3bab4a7ac4ad339
parent dc6e6fb1b47d610e9a1d695fe28877e42c083360
Author: Joris Vink <joris@coders.se>
Date:   Thu, 23 Apr 2015 10:24:00 +0200

Introduce new config option worker_accept_treshold

This configuration option limits the maximum number
of connections a worker process can accept() in a single
event loop.

It can be used to more evenly spread out incoming connections
across workers when new connections arrive in a burst.

Diffstat:
conf/kore.conf.example | 8++++++++
includes/kore.h | 1+
src/bsd.c | 4++++
src/config.c | 19+++++++++++++++++++
src/linux.c | 4++++
src/worker.c | 1+
6 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/conf/kore.conf.example b/conf/kore.conf.example @@ -24,6 +24,14 @@ workers 4 # Limit of maximum open files per worker. #worker_rlimit_nofiles 1024 +# Limit the number of new connections a worker can accept +# in a single event loop. +# NOTE: This can have a *MASSIVE* impact as this controls +# how new connections are spread across worker processes. +# +# This is disabled by default. +#worker_accept_treshold 0 + # Store the main process its pid in this file. #pidfile kore.pid diff --git a/includes/kore.h b/includes/kore.h @@ -361,6 +361,7 @@ extern u_int8_t worker_count; extern u_int32_t worker_rlimit_nofiles; extern u_int32_t worker_max_connections; extern u_int32_t worker_active_connections; +extern u_int32_t worker_accept_treshold; extern u_int64_t kore_websocket_maxframe; extern u_int64_t kore_websocket_timeout; extern u_int32_t kore_socket_backlog; diff --git a/src/bsd.c b/src/bsd.c @@ -153,6 +153,10 @@ kore_platform_event_wait(u_int64_t timer) while (worker_active_connections < worker_max_connections) { + if (worker_accept_treshold != 0 && + r >= worker_accept_treshold) + break; + if (!kore_connection_accept(l, &c)) { r = 1; break; diff --git a/src/config.c b/src/config.c @@ -44,6 +44,7 @@ static int configure_certfile(char **); static int configure_certkey(char **); static int configure_rlimit_nofiles(char **); static int configure_max_connections(char **); +static int configure_accept_treshold(char **); static int configure_ssl_cipher(char **); static int configure_ssl_dhparam(char **); static int configure_ssl_no_compression(char **); @@ -92,6 +93,7 @@ static struct { { "workers", configure_workers }, { "worker_max_connections", configure_max_connections }, { "worker_rlimit_nofiles", configure_rlimit_nofiles }, + { "worker_accept_treshold", configure_accept_treshold }, { "pidfile", configure_pidfile }, { "accesslog", configure_accesslog }, { "certfile", configure_certfile }, @@ -573,6 +575,23 @@ configure_rlimit_nofiles(char **argv) } static int +configure_accept_treshold(char **argv) +{ + int err; + + if (argv[1] == NULL) + return (KORE_RESULT_ERROR); + + worker_accept_treshold = kore_strtonum(argv[1], 0, 1, UINT_MAX, &err); + if (err != KORE_RESULT_OK) { + printf("bad value for worker_accept_treshold: %s\n", argv[1]); + return (KORE_RESULT_ERROR); + } + + return (KORE_RESULT_OK); +} + +static int configure_http_header_max(char **argv) { int err; diff --git a/src/linux.c b/src/linux.c @@ -130,6 +130,10 @@ kore_platform_event_wait(u_int64_t timer) while (worker_active_connections < worker_max_connections) { + if (worker_accept_treshold != 0 && + r >= worker_accept_treshold) + break; + if (!kore_connection_accept(l, &c)) { r = 1; break; diff --git a/src/worker.c b/src/worker.c @@ -68,6 +68,7 @@ static struct wlock *accept_lock; extern volatile sig_atomic_t sig_recv; struct kore_worker *worker = NULL; struct connection_list worker_clients; +u_int32_t worker_accept_treshold = 0; u_int32_t worker_rlimit_nofiles = 1024; u_int32_t worker_max_connections = 250; u_int32_t worker_active_connections = 0;