@cryptotaxi247 / netdata-1 / commits / 3889305d1

the static threaded web server can now be configured for the number of threads to open

Costa Tsaousis (ktsaou) committed Jan 8, 2018 at 00:37 UTC 3889305d12ad56a33e2a9a90e16f9886bfb0817b
4 files changed +93 -26
src/main.c
+1 -1
@@ -76,7 +76,7 @@ struct netdata_static_thread static_threads[] = {
76 {"PLUGINSD", NULL, NULL, 1, NULL, NULL, pluginsd_main},
77 {"WEB_SERVER[multi]", NULL, NULL, 1, NULL, NULL, socket_listen_main_multi_threaded},
78 {"WEB_SERVER[single]", NULL, NULL, 0, NULL, NULL, socket_listen_main_single_threaded},
79 - {"WEB_SERVER[static]", NULL, NULL, 0, NULL, NULL, socket_listen_main_static_threaded},
79 + {"WEB_SERVER[static1]", NULL, NULL, 0, NULL, NULL, socket_listen_main_static_threaded},
80 {"STREAM", NULL, NULL, 0, NULL, NULL, rrdpush_sender_thread},
81 {"STATSD", NULL, NULL, 1, NULL, NULL, statsd_main},
82
src/socket.c
+2 -2
@@ -1080,7 +1080,7 @@ static inline void poll_close_fd(struct poll *p, struct pollinfo *pi) {
1080 pi->del_callback(pf->fd, pi->socktype, pi->data);
1081 }
1082
1083 - info("POLLFD: closing fd %d", pf->fd);
1083 + // info("POLLFD: closing fd %d", pf->fd);
1084 close(pf->fd);
1085 pf->fd = -1;
1086 pf->events = 0;
@@ -1282,7 +1282,7 @@ void poll_events(LISTEN_SOCKETS *sockets
1282 }
1283 else {
1284 // accept ok
1285 - info("POLLFD: LISTENER: client '[%s]:%s' connected to '%s' on fd %d", client_ip, client_port, sockets->fds_names[i], nfd);
1285 + // info("POLLFD: LISTENER: client '[%s]:%s' connected to '%s' on fd %d", client_ip, client_port, sockets->fds_names[i], nfd);
1286 poll_add_fd(&p, nfd, SOCK_STREAM, POLLIN, POLLINFO_FLAG_CLIENT_SOCKET, client_ip, client_port);
1287
1288 // it may have reallocated them, so refresh our pointers
src/web_client.c
+9 -9
@@ -120,10 +120,6 @@ struct web_client *web_client_create_on_fd(int fd, const char *client_ip, const
120 w->origin[0] = '*';
121 web_client_enable_wait_receive(w);
122
123 - if(web_clients) web_clients->prev = w;
124 - w->next = web_clients;
125 - web_clients = w;
126 -
123 web_client_connected();
124 return(w);
125 }
@@ -305,15 +301,19 @@ void web_client_reset(struct web_client *w) {
301 }
302
303 struct web_client *web_client_free(struct web_client *w) {
304 + debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s port %s.", w->id, w->client_ip, w->client_port);
305 +
306 web_client_reset(w);
307
310 - struct web_client *n = w->next;
311 - if(w == web_clients) web_clients = n;
308 + struct web_client *n = NULL;
309 + if(web_server_mode != WEB_SERVER_MODE_STATIC_THREADED) {
310 + struct web_client *n = w->next;
311 + if (w == web_clients) web_clients = n;
312
313 - debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s port %s.", w->id, w->client_ip, w->client_port);
313 + if(w->prev) w->prev->next = w->next;
314 + if(w->next) w->next->prev = w->prev;
315 + }
316
315 - if(w->prev) w->prev->next = w->next;
316 - if(w->next) w->next->prev = w->prev;
317 buffer_free(w->response.header_output);
318 buffer_free(w->response.header);
319 buffer_free(w->response.data);
src/web_server.c
+81 -14
@@ -20,8 +20,11 @@ static void log_allocations(void)
20 mi = mallinfo();
21 if(mi.uordblks > used) {
22 int clients = 0;
23 - struct web_client *w;
24 - for(w = web_clients; w ; w = w->next) clients++;
23 +
24 + if(web_server_mode != WEB_SERVER_MODE_STATIC_THREADED) {
25 + struct web_client *w;
26 + for (w = web_clients; w; w = w->next) clients++;
27 + }
28
29 info("Allocated memory: used %d KB (+%d B), mmap %d KB (+%d B), heap %d KB (+%d B). %d web clients connected.",
30 mi.uordblks / 1024,
@@ -402,11 +405,18 @@ void *socket_listen_main_single_threaded(void *ptr) {
405 // --------------------------------------------------------------------------------------
406 // the main socket listener - STATIC-THREADED
407
408 +static __thread size_t web_server_static_connected = 0,
409 + web_server_static_disconnected = 0,
410 + web_server_static_receptions = 0,
411 + web_server_static_sends = 0;
412 +
413 // new TCP client connected
414 static void *web_server_add_callback(int fd, int socktype, short int *events, const char *client_ip, const char *client_port) {
415 (void)fd;
416 (void)socktype;
417
418 + web_server_static_connected++;
419 +
420 *events = POLLIN;
421
422 debug(D_WEB_CLIENT_ACCESS, "LISTENER on %d: new connection.", fd);
@@ -425,6 +435,8 @@ static void web_server_del_callback(int fd, int socktype, void *data) {
435 (void)fd;
436 (void)socktype;
437
438 + web_server_static_disconnected++;
439 +
440 struct web_client *w = (struct web_client *)data;
441
442 if(likely(w)) {
@@ -452,6 +464,8 @@ static int web_server_rcv_callback(int fd, int socktype, void *data, short int *
464 (void)fd;
465 (void)socktype;
466
467 + web_server_static_receptions++;
468 +
469 struct web_client *w = (struct web_client *)data;
470
471 if(unlikely(!web_client_has_wait_receive(w)))
@@ -489,6 +503,8 @@ static int web_server_snd_callback(int fd, int socktype, void *data, short int *
503 (void)fd;
504 (void)socktype;
505
506 + web_server_static_sends++;
507 +
508 struct web_client *w = (struct web_client *)data;
509
510 if(unlikely(!web_client_has_wait_send(w)))
@@ -506,31 +522,82 @@ static int web_server_snd_callback(int fd, int socktype, void *data, short int *
522 return web_server_check_client_status(w);
523 }
524
525 +static void socket_listen_main_static_threaded_worker_cleanup(void *ptr) {
526 + (void)ptr;
527 +
528 + info("stopped after %zu connects, %zu disconnects, %zu receptions and %zu sends",
529 + web_server_static_connected,
530 + web_server_static_disconnected,
531 + web_server_static_receptions,
532 + web_server_static_sends
533 + );
534 +}
535 +
536 +void *socket_listen_main_static_threaded_worker(void *ptr) {
537 + (void)ptr;
538 +
539 + netdata_thread_cleanup_push(socket_listen_main_static_threaded_worker_cleanup, ptr);
540 +
541 + poll_events(&api_sockets
542 + , web_server_add_callback
543 + , web_server_del_callback
544 + , web_server_rcv_callback
545 + , web_server_snd_callback
546 + , web_allow_connections_from
547 + , NULL
548 + );
549 +
550 + netdata_thread_cleanup_pop(1);
551 + return NULL;
552 +}
553 +
554 +static long long static_threaded_threads_count = 1;
555 +static netdata_thread_t *static_threaded_threads_ids = NULL;
556 +
557 static void socket_listen_main_static_threaded_cleanup(void *ptr) {
558 struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
559 if(static_thread->enabled) {
560 static_thread->enabled = 0;
561
514 - info("%s: cleaning up...", netdata_thread_tag());
562 + int i;
563 + for(i = 1; i < static_threaded_threads_count; i++) {
564 + info("stopping worker %d", i+1);
565 + netdata_thread_cancel(static_threaded_threads_ids[i]);
566 + }
567 +
568 + info("cleaning up...");
569 listen_sockets_close(&api_sockets);
570 }
571 }
572
573 void *socket_listen_main_static_threaded(void *ptr) {
574 netdata_thread_cleanup_push(socket_listen_main_static_threaded_cleanup, ptr);
521 - web_server_mode = WEB_SERVER_MODE_STATIC_THREADED;
575 + web_server_mode = WEB_SERVER_MODE_STATIC_THREADED;
576
523 - if(!api_sockets.opened)
524 - fatal("LISTENER: no listen sockets available.");
577 + if(!api_sockets.opened)
578 + fatal("LISTENER: no listen sockets available.");
579
526 - poll_events(&api_sockets
527 - , web_server_add_callback
528 - , web_server_del_callback
529 - , web_server_rcv_callback
530 - , web_server_snd_callback
531 - , web_allow_connections_from
532 - , NULL
533 - );
580 + // 6 threads is the optimal value
581 + // since 6 are the parallel connections browsers will do
582 + // so, if the machine has more CPUs, avoid using resources unnecessarily
583 + int def_thread_count = (processors > 6)?6:processors;
584 +
585 + static_threaded_threads_count = config_get_number(CONFIG_SECTION_WEB, "web server threads", def_thread_count);
586 + if(static_threaded_threads_count < 1) static_threaded_threads_count = 1;
587 +
588 + static_threaded_threads_ids = callocz((size_t)static_threaded_threads_count, sizeof(netdata_thread_t));
589 +
590 + int i;
591 + for(i = 1; i < static_threaded_threads_count; i++) {
592 + char tag[50 + 1];
593 + snprintfz(tag, 50, "WEB_SERVER[static%d]", i+1);
594 +
595 + info("starting worker %d", i+1);
596 + netdata_thread_create(&static_threaded_threads_ids[i], tag, NETDATA_THREAD_OPTION_DEFAULT, socket_listen_main_static_threaded_worker, NULL);
597 + }
598 +
599 + // and the main one
600 + socket_listen_main_static_threaded_worker(NULL);
601
602 netdata_thread_cleanup_pop(1);
603 return NULL;