Browse Source

Monitor server enhancement

- send buffer formated by stats functions to clients
- close client socket if needed
- allow bind to reuse an address if nobody listen on it
Yann Weber 4 years ago
parent
commit
d106364638
2 changed files with 60 additions and 9 deletions
  1. 1
    0
      include/monitor.h
  2. 59
    9
      src/monitor.c

+ 1
- 0
include/monitor.h View File

@@ -55,6 +55,7 @@ union pyfcgi_monitor_addr_u
55 55
 struct pyfcgi_monitor_s
56 56
 {
57 57
 	int sockserv;
58
+	int sockcli;
58 59
 	int sockargs[3];
59 60
 	pyfcgi_monitor_addr_t addr;
60 61
 

+ 59
- 9
src/monitor.c View File

@@ -6,7 +6,30 @@ static void clean_exit(int status)
6 6
 {
7 7
 	if(pyfcgi_mon.sockserv)
8 8
 	{
9
-		close(pyfcgi_mon.sockserv);
9
+		if(pyfcgi_mon.sockcli)
10
+		{
11
+			if(shutdown(pyfcgi_mon.sockcli, SHUT_RDWR) < 0)
12
+			{
13
+				pyfcgi_log(LOG_WARNING, "Unable to shutdown clisocket : %s",
14
+					strerror(errno));
15
+			}
16
+			if(close(pyfcgi_mon.sockcli) < 0)
17
+			{
18
+				pyfcgi_log(LOG_WARNING, "Unable to close clisocket : %s",
19
+					strerror(errno));
20
+			}
21
+		}
22
+		pyfcgi_log(LOG_INFO, "Closing listening socket...");
23
+		if(shutdown(pyfcgi_mon.sockserv, SHUT_RDWR) < 0)
24
+		{
25
+			pyfcgi_log(LOG_WARNING, "Unable to shutdown socket : %s",
26
+				strerror(errno));
27
+		}
28
+		if(close(pyfcgi_mon.sockserv) < 0)
29
+		{
30
+			pyfcgi_log(LOG_WARNING, "Unable to close socket : %s",
31
+				strerror(errno));
32
+		}
10 33
 	}
11 34
 	exit(status);
12 35
 }
@@ -82,7 +105,7 @@ int pyfcgi_monitor_IPC_init()
82 105
 void pyfcgi_monitor_loop()
83 106
 {
84 107
 	pyfcgi_monitor_addr_t addr;
85
-	int *sockargs;
108
+	int *sockargs, reuse;
86 109
 	socklen_t addrlen;
87 110
 
88 111
 	sockargs = pyfcgi_mon.sockargs;
@@ -118,12 +141,20 @@ void pyfcgi_monitor_loop()
118 141
 	{
119 142
 		addrlen = sizeof(struct sockaddr_un);
120 143
 	}
121
-	
144
+	reuse = 1;
145
+	if(setsockopt(pyfcgi_mon.sockserv, SOL_SOCKET, SO_REUSEADDR, &reuse,
146
+		sizeof(int)) < 0)
147
+	{
148
+		pyfcgi_log(LOG_WARNING, "Unable to set socket option : %s",
149
+			strerror(errno));
150
+	}
122 151
 	if(bind(pyfcgi_mon.sockserv, (struct sockaddr*)&addr, addrlen) < 0)
123 152
 	{
124
-		pyfcgi_log(LOG_ERR, "Unable to bind socket... Retrying in 10s");
153
+		pyfcgi_log(LOG_ERR, "Unable to bind socket... : %s",
154
+			strerror(errno));
155
+		pyfcgi_log(LOG_INFO, "Retrying in 10s");
125 156
 		close(pyfcgi_mon.sockserv);
126
-		sleep(30);
157
+		sleep(10);
127 158
 		clean_exit(PYFCGI_ERR);
128 159
 	}
129 160
 	pyfcgi_log(LOG_INFO, "Listening on %s", PyFCGI_conf.mon_socket);
@@ -146,9 +177,10 @@ void pyfcgi_monitor_stream_loop(pyfcgi_monitor_addr_t addr_serv)
146 177
 {
147 178
 	pyfcgi_monitor_addr_t cliaddr;
148 179
 	socklen_t addrlen;
149
-	int sockcli, err;
180
+	int sockcli, err, ret;
150 181
 	char ipstr[64];
151
-	char name[] = "PYFCGI_"VERSION"\n";
182
+	const char *buff;
183
+	size_t bufflen;
152 184
 
153 185
 	addrlen = sizeof(cliaddr);
154 186
 	if(listen(pyfcgi_mon.sockserv, PYFCGI_MONITOR_STREAM_BACKLOG) < 0)
@@ -160,7 +192,7 @@ void pyfcgi_monitor_stream_loop(pyfcgi_monitor_addr_t addr_serv)
160 192
 	
161 193
 	while(1)
162 194
 	{
163
-		sockcli = accept(pyfcgi_mon.sockserv,
195
+		sockcli = pyfcgi_mon.sockcli = accept(pyfcgi_mon.sockserv,
164 196
 			(struct sockaddr*)&cliaddr, &addrlen);
165 197
 		if(sockcli < 0)
166 198
 		{
@@ -176,10 +208,28 @@ void pyfcgi_monitor_stream_loop(pyfcgi_monitor_addr_t addr_serv)
176 208
 				strerror(errno));
177 209
 			strcpy(ipstr, "XXX");
178 210
 		}
211
+		if(!pyfcgi_stats_format())
212
+		{
213
+			pyfcgi_log(LOG_ERR, "Unable to format stats...");
214
+			close(sockcli);
215
+			continue;
216
+		}
217
+		pyfcgi_stats_buff(&buff, &bufflen);
179 218
 		pyfcgi_log(LOG_INFO, "Sending stats to %s", ipstr);
180 219
 		
181
-		send(sockcli, name, strlen(name), 0);
220
+		do
221
+		{
222
+			ret = send(sockcli, buff, bufflen, 0);
223
+			err = errno;
224
+		}while(ret == -1 && err == EINTR);
225
+		if(ret == -1)
226
+		{
227
+			pyfcgi_log(LOG_WARNING, "Unable to send stats to client : %s",
228
+				strerror(err));
229
+		}
230
+		shutdown(sockcli, SHUT_RDWR);
182 231
 		close(sockcli);
232
+		pyfcgi_mon.sockcli = 0;
183 233
 		
184 234
 		addrlen = sizeof(cliaddr);
185 235
 	}

Loading…
Cancel
Save