@cryptotaxi247 / netdata-1 / commits / d4c1c51fb

prevent multiple locks per web requests

Costa Tsaousis (ktsaou) committed May 20, 2016 at 23:16 UTC d4c1c51fb6819c789d08107c249b895a83a61740
5 files changed +55 -26
src/global_statistics.c
+1 -1
@@ -5,7 +5,7 @@
5
6 #include "global_statistics.h"
7
8 -struct global_statistics global_statistics = { 0ULL, 0ULL, 0ULL, 0ULL };
8 +struct global_statistics global_statistics = { 0, 0ULL, 0ULL, 0ULL, 0ULL};
9
10 pthread_mutex_t global_statistics_mutex = PTHREAD_MUTEX_INITIALIZER;
11
src/global_statistics.h
+5 -5
@@ -5,11 +5,11 @@
5 // global statistics
6
7 struct global_statistics {
8 - unsigned long long connected_clients;
9 - unsigned long long web_requests;
10 - unsigned long long bytes_received;
11 - unsigned long long bytes_sent;
12 -
8 + unsigned long volatile connected_clients;
9 + unsigned long long volatile web_requests;
10 + unsigned long long volatile web_usec;
11 + unsigned long long volatile bytes_received;
12 + unsigned long long volatile bytes_sent;
13 };
14
15 extern struct global_statistics global_statistics;
src/plugin_proc.c
+27 -2
@@ -18,7 +18,8 @@
18
19 void *proc_main(void *ptr)
20 {
21 - if(ptr) { ; }
21 + static unsigned long long old_web_requests = 0, old_web_usec = 0;
22 + (void)ptr;
23
24 info("PROC Plugin thread created with task id %d", gettid());
25
@@ -77,7 +78,7 @@ void *proc_main(void *ptr)
78 unsigned long long sunext = (time(NULL) - (time(NULL) % rrd_update_every) + rrd_update_every) * 1000000ULL;
79 unsigned long long sunow;
80
80 - RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL;
81 + RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL;
82
83 for(;1;) {
84 if(unlikely(netdata_exit)) break;
@@ -310,6 +311,30 @@ void *proc_main(void *ptr)
311
312 // ----------------------------------------------------------------
313
314 + if(!stduration) stduration = rrdset_find("netdata.response_time");
315 + if(!stduration) {
316 + stduration = rrdset_create("netdata", "response_time", NULL, "netdata", NULL, "NetData Average API Response Time", "ms/request", 130400, rrd_update_every, RRDSET_TYPE_LINE);
317 +
318 + rrddim_add(stduration, "response_time", "response time", 1, 1000, RRDDIM_ABSOLUTE);
319 + }
320 + else rrdset_next(stduration);
321 +
322 + unsigned long long gweb_usec = global_statistics.web_usec;
323 + unsigned long long gweb_requests = global_statistics.web_requests;
324 +
325 + unsigned long long web_usec = gweb_usec - old_web_usec;
326 + unsigned long long web_requests = gweb_requests - old_web_requests;
327 +
328 + old_web_usec = gweb_usec;
329 + old_web_requests = gweb_requests;
330 +
331 + if(!web_requests) web_requests = 1;
332 +
333 + rrddim_set(stduration, "response_time", web_usec / web_requests);
334 + rrdset_done(stduration);
335 +
336 + // ----------------------------------------------------------------
337 +
338 registry_statistics();
339 }
340 }
src/web_client.c
+19 -18
@@ -146,6 +146,19 @@ void web_client_reset(struct web_client *w)
146 struct timeval tv;
147 gettimeofday(&tv, NULL);
148
149 + debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id);
150 +
151 + if(w->stats_received_bytes || w->stats_sent_bytes) {
152 + global_statistics_lock();
153 + global_statistics.web_requests++;
154 + global_statistics.web_usec += usecdiff(&tv, &w->tv_in);
155 + global_statistics.bytes_received += w->stats_received_bytes;
156 + global_statistics.bytes_sent += w->stats_sent_bytes;
157 + global_statistics_unlock();
158 + }
159 + w->stats_received_bytes = 0;
160 + w->stats_sent_bytes = 0;
161 +
162 long sent = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len;
163
164 #ifdef NETDATA_WITH_ZLIB
@@ -166,8 +179,6 @@ void web_client_reset(struct web_client *w)
179 w->last_url
180 );
181
169 - debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id);
170 -
182 if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) {
183 debug(D_WEB_CLIENT, "%llu: Closing filecopy input file.", w->id);
184 close(w->ifd);
@@ -1341,10 +1352,6 @@ void web_client_process(struct web_client *w) {
1352 else { // what_to_do == 0
1353 gettimeofday(&w->tv_in, NULL);
1354
1344 - global_statistics_lock();
1345 - global_statistics.web_requests++;
1346 - global_statistics_unlock();
1347 -
1355 // copy the URL - we are going to overwrite parts of it
1356 // FIXME -- we should avoid it
1357 strncpyz(w->last_url, w->decoded_url, URL_MAX);
@@ -1736,11 +1743,8 @@ void web_client_process(struct web_client *w) {
1743 , w->id
1744 , buffer_strlen(w->response.header_output)
1745 , bytes);
1739 - else {
1740 - global_statistics_lock();
1741 - global_statistics.bytes_sent += bytes;
1742 - global_statistics_unlock();
1743 - }
1746 + else
1747 + w->stats_sent_bytes += bytes;
1748
1749 // enable TCP_NODELAY, to send all data immediately at the next send()
1750 flag = 1;
@@ -2107,10 +2111,8 @@ void *web_client_main(void *ptr)
2111 errno = 0;
2112 break;
2113 }
2110 -
2111 - global_statistics_lock();
2112 - global_statistics.bytes_sent += bytes;
2113 - global_statistics_unlock();
2114 + else
2115 + w->stats_sent_bytes += bytes;
2116 }
2117
2118 if(w->wait_receive && FD_ISSET(w->ifd, &ifds)) {
@@ -2120,6 +2122,8 @@ void *web_client_main(void *ptr)
2122 errno = 0;
2123 break;
2124 }
2125 + else
2126 + w->stats_received_bytes += bytes;
2127
2128 if(w->mode == WEB_CLIENT_MODE_NORMAL) {
2129 debug(D_WEB_CLIENT, "%llu: Attempting to process received data (%ld bytes).", w->id, bytes);
@@ -2127,9 +2131,6 @@ void *web_client_main(void *ptr)
2131 web_client_process(w);
2132 }
2133
2130 - global_statistics_lock();
2131 - global_statistics.bytes_received += bytes;
2132 - global_statistics_unlock();
2134 }
2135 }
2136
src/web_client.h
+3
@@ -83,6 +83,9 @@ struct web_client {
83 int wait_receive;
84 int wait_send;
85
86 + unsigned long stats_received_bytes;
87 + unsigned long stats_sent_bytes;
88 +
89 struct web_client *prev;
90 struct web_client *next;
91 };