Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 410 lines (323 sloc) 12.62 kb
3684083 preliminary snapshotting support
roberto@debian32 authored
1 #include "uwsgi.h"
2
3 extern struct uwsgi_server uwsgi;
4
630054b better wakeup of workers
roberto@debian32 authored
5 void worker_wakeup() {}
6
3684083 preliminary snapshotting support
roberto@debian32 authored
7 void master_check_cluster_nodes() {
8
9 int i;
10
11 for (i = 0; i < MAX_CLUSTER_NODES; i++) {
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
12 struct uwsgi_cluster_node *ucn = &uwsgi.shared->nodes[i];
13
14 if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_STATIC && ucn->status == UWSGI_NODE_FAILED) {
15 // should i retry ?
16 if (uwsgi.master_cycles % ucn->errors == 0) {
17 if (!uwsgi_ping_node(i, uwsgi.wsgi_req)) {
18 ucn->status = UWSGI_NODE_OK;
19 uwsgi_log("re-enabled cluster node %d/%s\n", i, ucn->name);
20 }
21 else {
22 ucn->errors++;
23 }
24 }
25 }
26 else if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_DYNAMIC) {
27 // if the last_seen attr is higher than 30 secs ago, mark the node as dead
28 if ((uwsgi.current_time - ucn->last_seen) > 30) {
29 uwsgi_log_verbose("no presence announce in the last 30 seconds by node %s, i assume it is dead.\n", ucn->name);
30 ucn->name[0] = 0;
31 }
32 }
33 }
3684083 preliminary snapshotting support
roberto@debian32 authored
34 }
35
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
36 void uwsgi_fixup_fds(int wid, int muleid) {
3684083 preliminary snapshotting support
roberto@debian32 authored
37
789e333 master_fixup on reloads
roberto@goyle authored
38 int i;
43e6664 --cheap option
roberto@debian32 authored
39
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
40 // close the cache server
41 if (uwsgi.cache_server_fd != -1) {
42 close(uwsgi.cache_server_fd);
43 }
44
0ba1b98 implemented target='workers' for signal infrastructure
roberto@maverick64 authored
45 if (uwsgi.master_process) {
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
46 // fix the communication pipe
47 close(uwsgi.shared->worker_signal_pipe[0]);
48 for(i=1;i<=uwsgi.numproc;i++) {
49 if (uwsgi.workers[i].signal_pipe[0] != -1) close(uwsgi.workers[i].signal_pipe[0]);
50 if (i != wid) {
51 if (uwsgi.workers[i].signal_pipe[1] != -1) close(uwsgi.workers[i].signal_pipe[1]);
52 }
53 }
54 #ifdef UWSGI_SPOOLER
19c5bfb fixed a spooler signal bug spotted by Gabriele Giaccari
roberto@debian32 authored
55 if (uwsgi.shared->spooler_pid != getpid()) {
56 if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
57 if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
58 }
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
59 #endif
0ba1b98 implemented target='workers' for signal infrastructure
roberto@maverick64 authored
60
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
61 if (uwsgi.shared->mule_signal_pipe[0] != -1) close(uwsgi.shared->mule_signal_pipe[0]);
4fb5a84 improved multi-mule support
roberto@debian32 authored
62
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
63 if (muleid == 0) {
64 if (uwsgi.shared->mule_signal_pipe[1] != -1) close(uwsgi.shared->mule_signal_pipe[1]);
4fb5a84 improved multi-mule support
roberto@debian32 authored
65 if (uwsgi.shared->mule_queue_pipe[1] != -1) close(uwsgi.shared->mule_queue_pipe[1]);
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
66 }
67
68 for(i=0;i<uwsgi.mules_cnt;i++) {
69 if (uwsgi.mules[i].signal_pipe[0] != -1) close(uwsgi.mules[i].signal_pipe[0]);
70 if (muleid != i+1) {
71 if (uwsgi.mules[i].signal_pipe[1] != -1) close(uwsgi.mules[i].signal_pipe[1]);
72 if (uwsgi.mules[i].queue_pipe[1] != -1) close(uwsgi.mules[i].queue_pipe[1]);
73 }
74 }
75
1d5b052 initial farm implementation
roberto@debian32 authored
76 for(i=0;i<uwsgi.farms_cnt;i++) {
77 if (uwsgi.farms[i].signal_pipe[0] != -1) close(uwsgi.farms[i].signal_pipe[0]);
78
79 if (muleid == 0) {
80 if (uwsgi.farms[i].signal_pipe[1] != -1) close(uwsgi.farms[i].signal_pipe[1]);
81 if (uwsgi.farms[i].queue_pipe[1] != -1) close(uwsgi.farms[i].queue_pipe[1]);
82 }
83 }
84
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
85 }
86
87
88 }
0ba1b98 implemented target='workers' for signal infrastructure
roberto@maverick64 authored
89
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
90 int uwsgi_respawn_worker(int wid) {
91
92 int respawns = uwsgi.workers[wid].respawn_count;
93 int i;
0ba1b98 implemented target='workers' for signal infrastructure
roberto@maverick64 authored
94
b39a10f procname initial management
roberto@debian32 authored
95 pid_t pid = uwsgi_fork(uwsgi.workers[wid].name);
43e6664 --cheap option
roberto@debian32 authored
96
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
97 if (pid == 0) {
630054b better wakeup of workers
roberto@debian32 authored
98 signal(SIGWINCH, worker_wakeup);
bc6acf8 use SIGTSTP instead of SIGWINCH for pause/suspend/resume
roberto@debian32 authored
99 signal(SIGTSTP, worker_wakeup);
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
100 uwsgi.mywid = wid;
101 uwsgi.mypid = getpid();
102 uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
103 uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
104 uwsgi.workers[uwsgi.mywid].harakiri = 0;
2d1a9a0 reduce a potetial race conditions in evil reloads
roberto@oneiric64 authored
105
106 uwsgi.workers[uwsgi.mywid].rss_size = 0;
107 uwsgi.workers[uwsgi.mywid].vsz_size = 0;
5594503 pcre support in subscription system
roberto@debian32 authored
108 // do not reset worker counters on reload !!!
109 //uwsgi.workers[uwsgi.mywid].requests = 0;
5b5e3a1 added delta_requests
roberto@goyle authored
110 // ...but maintain a delta counter (yes this is racy in multithread)
111 uwsgi.workers[uwsgi.mywid].delta_requests = 0;
5594503 pcre support in subscription system
roberto@debian32 authored
112 //uwsgi.workers[uwsgi.mywid].failed_requests = 0;
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
113 uwsgi.workers[uwsgi.mywid].respawn_count++;
114 uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
115 uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
a05f459 preliminary cheaper implementation
roberto@debian32 authored
116 uwsgi.workers[uwsgi.mywid].cheaped = 0;
8566257 implemented --mule-harakiri
roberto@debian32 authored
117 uwsgi.workers[uwsgi.mywid].busy = 0;
3a099d0 added --pause/--suspend/--resume
roberto@sirius authored
118 uwsgi.workers[uwsgi.mywid].suspended = 0;
8566257 implemented --mule-harakiri
roberto@debian32 authored
119 uwsgi.workers[uwsgi.mywid].sig = 0;
789e333 master_fixup on reloads
roberto@goyle authored
120
0ab55fe added support for regexp in UWSGI_APPID
roberto@debian32 authored
121 // reset the apps count with a copy from the master
122 uwsgi.workers[uwsgi.mywid].apps_cnt = uwsgi.workers[0].apps_cnt;
dd344bf fixed a bug in multiapp mode
roberto@debian32 authored
123
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
124 uwsgi_fixup_fds(wid, 0);
125
126 uwsgi.my_signal_socket = uwsgi.workers[wid].signal_pipe[1];
cae0f9b fixed fd leaks generated by new signal improvements
roberto@natty32 authored
127
bd1b3b8 allows spooler to manage signals
roberto@maverick64 authored
128 if (uwsgi.master_process) {
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
129 if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
130 for (i = 0; i < 0xFF; i++) {
131 if (uwsgi.p[i]->master_fixup) {
132 uwsgi.p[i]->master_fixup(1);
133 }
134 }
135 }
789e333 master_fixup on reloads
roberto@goyle authored
136 }
b7b7521 refactored fds closing and socketpair
roberto@debian32 authored
137
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
138 return 1;
139 }
140 else if (pid < 1) {
141 uwsgi_error("fork()");
142 }
143 else {
144 if (respawns > 0) {
ffb8752 report corrent worker id in cheap mode
roberto@mrspurr authored
145 uwsgi_log("Respawned uWSGI worker %d (new pid: %d)\n", wid, (int) pid);
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
146 }
147 else {
148 uwsgi_log("spawned uWSGI worker %d (pid: %d, cores: %d)\n", wid, pid, uwsgi.cores);
149 }
150 }
151
152 return 0;
153 }
154
155
156 void uwsgi_manage_signal_cron(time_t now) {
157
158 struct tm *uwsgi_cron_delta;
159 int i;
160
161 uwsgi.current_time = now;
162 uwsgi_cron_delta = localtime(&uwsgi.current_time);
163
164 if (uwsgi_cron_delta) {
165
166 // fix month
167 uwsgi_cron_delta->tm_mon++;
168
169 uwsgi_lock(uwsgi.cron_table_lock);
170 for (i = 0; i < ushared->cron_cnt; i++) {
171
172 struct uwsgi_cron *ucron = &ushared->cron[i];
173 int uc_minute, uc_hour, uc_day, uc_month, uc_week;
174
175 uc_minute = ucron->minute;
176 uc_hour = ucron->hour;
177 uc_day = ucron->day;
178 uc_month = ucron->month;
179 uc_week = ucron->week;
180
181 if (ucron->minute == -1)
182 uc_minute = uwsgi_cron_delta->tm_min;
183 if (ucron->hour == -1)
184 uc_hour = uwsgi_cron_delta->tm_hour;
185 if (ucron->month == -1)
186 uc_month = uwsgi_cron_delta->tm_mon;
ff2d3c2 fixed a bug in cron management
roberto@oneiric64 authored
187 if (ucron->day == -1)
188 uc_day = uwsgi_cron_delta->tm_mday;
189 if (ucron->week == -1)
190 uc_week = uwsgi_cron_delta->tm_wday;
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
191
6f57902 another cron fix
roberto@oneiric64 authored
192 int run_task = 0;
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
193 // mday and wday are ORed
6f57902 another cron fix
roberto@oneiric64 authored
194 if (ucron->day != -1 && ucron->week != -1) {
195 if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
196 run_task = 1;
197 }
198 }
199 else {
200 if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
201 run_task = 1;
202 }
203 }
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
204
205
6f57902 another cron fix
roberto@oneiric64 authored
206 if (run_task == 1) {
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
207 // date match, signal it ?
208 if (uwsgi.current_time - ucron->last_job > 60) {
209 uwsgi_route_signal(ucron->sig);
210 ucron->last_job = uwsgi.current_time;
211 }
212 }
213
214 }
215 uwsgi_unlock(uwsgi.cron_table_lock);
216 }
217 else {
218 uwsgi_error("localtime()");
219 }
220
221 }
222
223 void uwsgi_manage_command_cron(time_t now) {
224
225 struct tm *uwsgi_cron_delta;
226
227 struct uwsgi_cron *current_cron = uwsgi.crons;
228 int uc_minute, uc_hour, uc_day, uc_month, uc_week;
229
230 uwsgi.current_time = now;
231 uwsgi_cron_delta = localtime(&uwsgi.current_time);
232
233
234 if (!uwsgi_cron_delta) {
235 uwsgi_error("localtime()");
236 return;
237 }
238
239 while (current_cron) {
240
241
242 uc_minute = current_cron->minute;
243 uc_hour = current_cron->hour;
244 uc_day = current_cron->day;
245 uc_month = current_cron->month;
246 uc_week = current_cron->week;
247
248 if (current_cron->minute == -1)
249 uc_minute = uwsgi_cron_delta->tm_min;
250 if (current_cron->hour == -1)
251 uc_hour = uwsgi_cron_delta->tm_hour;
252 if (current_cron->month == -1)
253 uc_month = uwsgi_cron_delta->tm_mon;
ff2d3c2 fixed a bug in cron management
roberto@oneiric64 authored
254 if (current_cron->day == -1)
255 uc_day = uwsgi_cron_delta->tm_mday;
256 if (current_cron->week == -1)
257 uc_week = uwsgi_cron_delta->tm_wday;
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
258
6f57902 another cron fix
roberto@oneiric64 authored
259 int run_task = 0;
260 // mday and wday are ORed
261 if (current_cron->day != -1 && current_cron->week != -1) {
262 if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && (uwsgi_cron_delta->tm_mday == uc_day || uwsgi_cron_delta->tm_wday == uc_week)) {
263 run_task = 1;
264 }
265 }
266 else {
267 if (uwsgi_cron_delta->tm_min == uc_minute && uwsgi_cron_delta->tm_hour == uc_hour && uwsgi_cron_delta->tm_mon == uc_month && uwsgi_cron_delta->tm_mday == uc_day && uwsgi_cron_delta->tm_wday == uc_week) {
268 run_task = 1;
269 }
270 }
271
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
272
6f57902 another cron fix
roberto@oneiric64 authored
273 if (run_task == 1) {
3a9d13b --cron option, thanks Simon Litchfield for the idea
roberto@debian32 authored
274
275 // date match, run command ?
276 if (uwsgi.current_time - current_cron->last_job > 60) {
277 //call command
278 if (current_cron->command) {
279 if (uwsgi_run_command(current_cron->command) >=0) {
280 uwsgi_log_verbose("[uWSGI-cron] running %s\n", current_cron->command);
281 }
282 }
283 current_cron->last_job = uwsgi.current_time;
284 }
285 }
286
287
288
289 current_cron = current_cron->next;
290 }
291
292
3684083 preliminary snapshotting support
roberto@debian32 authored
293 }
d5b7698 added --stats
roberto@debian32 authored
294
531a850 first almost-working commit for uWSGI mules
roberto@debian32 authored
295 #define stats_send_llu(x, y) fprintf(output, x, (long long unsigned int) y)
296 #define stats_send(x, y) fprintf(output, x, y)
297
d5b7698 added --stats
roberto@debian32 authored
298 void uwsgi_send_stats(int fd) {
299
300 int i,j;
301 struct sockaddr_un client_src;
302 struct uwsgi_app *ua;
303 socklen_t client_src_len = 0;
304 int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
305 if (client_fd < 0) {
306 uwsgi_error("accept()");
307 return;
308 }
309
310 FILE *output = fdopen(client_fd, "w");
311 if (!output) {
312 uwsgi_error("fdopen()");
313 close(client_fd);
314 return;
315 }
316
605e5b5 export listen_queue size in stats
roberto@debian32 authored
317 stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
318
1494c62 non-linux fix
roberto@freebsd64 authored
319 #ifdef __linux__
605e5b5 export listen_queue size in stats
roberto@debian32 authored
320 stats_send_llu("\"listen_queue\": %llu,\n", uwsgi.shared->ti.tcpi_unacked);
1494c62 non-linux fix
roberto@freebsd64 authored
321 #endif
605e5b5 export listen_queue size in stats
roberto@debian32 authored
322
e54fa9b added --emperor-stats
roberto@debian32 authored
323 fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
324 fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
325
326 char *cwd = uwsgi_get_cwd();
327 stats_send("\"cwd\": \"%s\",\n", cwd);
328 free(cwd);
329
605e5b5 export listen_queue size in stats
roberto@debian32 authored
330 fprintf(output, "\"workers\": [\n");
d5b7698 added --stats
roberto@debian32 authored
331
332 for (i = 0; i < uwsgi.numproc; i++) {
333 fprintf(output,"\t{");
334
335 fprintf(output,"\"id\": %d, ", uwsgi.workers[i+1].id);
2cae07a fixed 64bit compilation
roberto@solrisexpress authored
336 fprintf(output,"\"pid\": %d, ", (int) uwsgi.workers[i+1].pid);
531a850 first almost-working commit for uWSGI mules
roberto@debian32 authored
337 stats_send_llu("\"requests\": %llu, ", uwsgi.workers[i+1].requests);
5b5e3a1 added delta_requests
roberto@goyle authored
338 stats_send_llu("\"delta_requests\": %llu, ", uwsgi.workers[i+1].delta_requests);
531a850 first almost-working commit for uWSGI mules
roberto@debian32 authored
339 stats_send_llu("\"exceptions\": %llu, ", uwsgi.workers[i+1].exceptions);
e54fa9b added --emperor-stats
roberto@debian32 authored
340 stats_send_llu("\"signals\": %llu, ", uwsgi.workers[i+1].signals);
d5b7698 added --stats
roberto@debian32 authored
341
342 if (uwsgi.workers[i + 1].cheaped) {
343 fprintf(output,"\"status\": \"cheap\", ");
344 }
3a099d0 added --pause/--suspend/--resume
roberto@sirius authored
345 else if (uwsgi.workers[i + 1].suspended) {
346 fprintf(output,"\"status\": \"pause\", ");
347 }
d5b7698 added --stats
roberto@debian32 authored
348 else {
8566257 implemented --mule-harakiri
roberto@debian32 authored
349 if (uwsgi.workers[i + 1].sig) {
350 fprintf(output,"\"status\": \"sig%d\", ", uwsgi.workers[i + 1].signum);
351 }
352 else if (uwsgi.workers[i + 1].busy) {
d5b7698 added --stats
roberto@debian32 authored
353 fprintf(output,"\"status\": \"busy\", ");
354 }
355 else {
356 fprintf(output,"\"status\": \"idle\", ");
357 }
358 }
359
531a850 first almost-working commit for uWSGI mules
roberto@debian32 authored
360 stats_send_llu("\"rss\": %llu, ", uwsgi.workers[i+1].rss_size);
361 stats_send_llu("\"vsz\": %llu, ", uwsgi.workers[i+1].vsz_size);
d5b7698 added --stats
roberto@debian32 authored
362
531a850 first almost-working commit for uWSGI mules
roberto@debian32 authored
363 stats_send_llu("\"running_time\": %llu, ", uwsgi.workers[i+1].running_time);
364 stats_send_llu("\"last_spawn\": %llu, ", uwsgi.workers[i+1].last_spawn);
365 stats_send_llu("\"respawn_count\": %llu, ", uwsgi.workers[i+1].respawn_count);
366 stats_send_llu("\"tx\": %llu, ", uwsgi.workers[i+1].tx);
367 stats_send_llu("\"avg_rt\": %llu, ", uwsgi.workers[i+1].avg_response_time);
e54fa9b added --emperor-stats
roberto@debian32 authored
368
d5b7698 added --stats
roberto@debian32 authored
369 fprintf(output,"\"apps\": [\n");
370
371 for(j=0;j<uwsgi.workers[i+1].apps_cnt;j++) {
372 ua = &uwsgi.workers[i+1].apps[j];
373 fprintf(output,"\t\t{ ");
374
375 fprintf(output, "\"id\": %d, ", j);
376 fprintf(output, "\"modifier1\": %d, ", ua->modifier1);
377 fprintf(output, "\"mountpoint\": \"%.*s\", ", ua->mountpoint_len, ua->mountpoint);
378
531a850 first almost-working commit for uWSGI mules
roberto@debian32 authored
379 stats_send_llu( "\"requests\": %llu, ", ua->requests);
380 stats_send_llu( "\"exceptions\": %llu, ", ua->exceptions);
d5b7698 added --stats
roberto@debian32 authored
381
382 if (ua->chdir) {
383 fprintf(output, "\"chdir\": \"%s\", ", ua->chdir);
384 }
385 else {
386 fprintf(output, "\"chdir\": \"\" ");
387 }
388
389 if (j == uwsgi.workers[i+1].apps_cnt-1) {
390 fprintf(output,"}\n");
391 }
392 else {
393 fprintf(output,"},\n");
394 }
395 }
396
397 fprintf(output,"\t\t]");
398
399 if (i == uwsgi.numproc-1) {
400 fprintf(output,"}\n");
401 }
402 else {
403 fprintf(output,"},\n");
404 }
405 }
406
407 fprintf(output,"]}\n");
408 fclose(output);
409 }
Something went wrong with that request. Please try again.