Lines 30-37
Link Here
|
30 |
#include "fcgid_spawn_ctl.h" |
30 |
#include "fcgid_spawn_ctl.h" |
31 |
#include "fcgid_protocol.h" |
31 |
#include "fcgid_protocol.h" |
32 |
#include "fcgid_bucket.h" |
32 |
#include "fcgid_bucket.h" |
33 |
#define FCGID_APPLY_TRY_COUNT 2 |
33 |
/* FCGID_REQUEST_COUNT: |
34 |
#define FCGID_REQUEST_COUNT 32 |
34 |
* how many times to attempt a spawn request */ |
|
|
35 |
#define FCGID_REQUEST_COUNT 8 |
36 |
/* FCGID_REQUEST_INITIAL_STEP: |
37 |
* The initial iterations of the inner loop */ |
38 |
#define FCGID_REQUEST_INITIAL_STEP 2 |
39 |
/* FCGID_REQUEST_INITIAL_SLEEP: |
40 |
* The initial sleep time in ms of the inner loop */ |
41 |
#define FCGID_REQUEST_INITIAL_SLEEP 50 |
42 |
/* FCGID_REQUEST_STEPSIZE: |
43 |
* every FCGID_REQUEST_COUNT loop, increase the inner loop by this size */ |
44 |
#define FCGID_REQUEST_STEPSIZE 6 |
45 |
/* FCGID_REQUEST_SLEEPSIZE: |
46 |
* every FCGID_REQUEST_COUNT loop, increase the inner loop sleeptime |
47 |
* by FCGID_REQUEST_SLEEPSIZE miliseconds */ |
48 |
#define FCGID_REQUEST_SLEEPSIZE 150 |
49 |
/* FCGID_REQUEST_STEPCOUNT: |
50 |
* how many FCGID_REQUEST_COUNT loop iterations to increase the |
51 |
* inner loop by FCGID_REQUEST_STEPSIZE */ |
52 |
#define FCGID_REQUEST_STEPCOUNT 4 |
53 |
/* FCGID_REQUEST_SLEEPCOUNT: |
54 |
* how many FCGID_REQUEST_COUNT loop iterations to increase the |
55 |
* inner loop by FCGID_REQUEST_SLEEPSIZE msec */ |
56 |
#define FCGID_REQUEST_SLEEPCOUNT 4 |
35 |
#define FCGID_BRIGADE_CLEAN_STEP 32 |
57 |
#define FCGID_BRIGADE_CLEAN_STEP 32 |
36 |
|
58 |
|
37 |
static fcgid_procnode *apply_free_procnode(request_rec *r, |
59 |
static fcgid_procnode *apply_free_procnode(request_rec *r, |
Lines 425-431
Link Here
|
425 |
{ |
447 |
{ |
426 |
fcgid_command fcgi_request; |
448 |
fcgid_command fcgi_request; |
427 |
fcgid_bucket_ctx *bucket_ctx; |
449 |
fcgid_bucket_ctx *bucket_ctx; |
428 |
int i, j, cond_status; |
450 |
int i, j, cond_status, wait_msec, try_spawn; |
429 |
const char *location = NULL; |
451 |
const char *location = NULL; |
430 |
|
452 |
|
431 |
bucket_ctx = apr_pcalloc(r->pool, sizeof(*bucket_ctx)); |
453 |
bucket_ctx = apr_pcalloc(r->pool, sizeof(*bucket_ctx)); |
Lines 434-467
Link Here
|
434 |
apr_pool_cleanup_register(r->pool, bucket_ctx, |
456 |
apr_pool_cleanup_register(r->pool, bucket_ctx, |
435 |
bucket_ctx_cleanup, apr_pool_cleanup_null); |
457 |
bucket_ctx_cleanup, apr_pool_cleanup_null); |
436 |
procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf); |
458 |
procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf); |
437 |
|
459 |
bucket_ctx->ipc.connect_timeout = |
|
|
460 |
fcgi_request.cmdopts.ipc_connect_timeout; |
461 |
bucket_ctx->ipc.communation_timeout = |
462 |
fcgi_request.cmdopts.ipc_comm_timeout; |
463 |
|
464 |
/* our initial wait time is short */ |
465 |
wait_msec = FCGID_REQUEST_INITIAL_SLEEP; |
466 |
/* initially we try to spawn a processes after failing to apply 2 times */ |
467 |
try_spawn = FCGID_REQUEST_INITIAL_STEP; |
438 |
/* Try to get a connected ipc handle */ |
468 |
/* Try to get a connected ipc handle */ |
439 |
for (i = 0; i < FCGID_REQUEST_COUNT; i++) { |
469 |
for (i = 0; i < FCGID_REQUEST_COUNT; i++) { |
440 |
/* Apply a free process slot, send a spawn request if I can't get one */ |
470 |
/* Apply a free process slot, send a spawn request if I can't get one */ |
441 |
for (j = 0; j < FCGID_APPLY_TRY_COUNT; j++) { |
471 |
for (j = 0; j < try_spawn; j++) { |
442 |
bucket_ctx->ipc.connect_timeout = |
|
|
443 |
fcgi_request.cmdopts.ipc_connect_timeout; |
444 |
bucket_ctx->ipc.communation_timeout = |
445 |
fcgi_request.cmdopts.ipc_comm_timeout; |
446 |
|
472 |
|
447 |
/* Apply a process slot */ |
473 |
/* Apply a process slot */ |
448 |
bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request); |
474 |
bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request); |
449 |
if (bucket_ctx->procnode) |
475 |
if (bucket_ctx->procnode) |
450 |
break; |
476 |
break; |
451 |
|
477 |
|
452 |
/* Avoid sleeping the very first time through if there are no |
478 |
/* We couldn't get a free process slot, if it was the very |
453 |
busy processes; the problem is just that we haven't spawned |
479 |
first try, lets check if any were spawned at all */ |
454 |
anything yet, so waiting is pointless */ |
480 |
if (i == 0 && j == 0 |
455 |
if (i > 0 || j > 0 || count_busy_processes(r, &fcgi_request)) { |
481 |
&& count_busy_processes(r, &fcgi_request)==0) { |
456 |
apr_sleep(apr_time_from_sec(1)); |
482 |
/* there are no processes so try to spawn one */ |
|
|
483 |
procmgr_send_spawn_cmd(&fcgi_request, r); |
457 |
|
484 |
|
458 |
bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request); |
485 |
bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request); |
459 |
if (bucket_ctx->procnode) |
486 |
if (bucket_ctx->procnode) |
460 |
break; |
487 |
break; |
461 |
} |
488 |
} |
462 |
|
489 |
|
463 |
/* Send a spawn request if I can't get a process slot */ |
490 |
/* now wait a bit for a process to free up */ |
464 |
procmgr_send_spawn_cmd(&fcgi_request, r); |
491 |
apr_sleep(apr_time_from_msec(wait_msec)); |
|
|
492 |
|
465 |
} |
493 |
} |
466 |
|
494 |
|
467 |
/* Connect to the fastcgi server */ |
495 |
/* Connect to the fastcgi server */ |
Lines 476-481
Link Here
|
476 |
else |
504 |
else |
477 |
break; |
505 |
break; |
478 |
} |
506 |
} |
|
|
507 |
|
508 |
/* It seems to be busy, every iteration we try to spawn less |
509 |
* often as its more and more likely we hit the max processes |
510 |
* limit. Also sleep longer so we don't waste too much cycles. |
511 |
* When nearing the end of our retry lifitime, decrease sleep |
512 |
* time again so we still have a chance at getting a process. */ |
513 |
/* loop iterations: |
514 |
0) 2 x 50ms = 100ms |
515 |
1) 8 x 200ms = 1600ms |
516 |
2) 14 x 350ms = 4900ms |
517 |
3) 20 x 500ms = 10000ms |
518 |
4) 26 x 650ms = 16900ms |
519 |
5) 26 x 500ms = 13000ms |
520 |
6) 26 x 350ms = 9100ms |
521 |
7) 26 x 200ms = 5200ms |
522 |
-------- + |
523 |
60800ms (8x spawn, 148 apply) |
524 |
Old: 64000ms (64x spawn, 128 apply) |
525 |
*/ |
526 |
if(i < FCGID_REQUEST_STEPCOUNT){ |
527 |
try_spawn+=FCGID_REQUEST_STEPSIZE; |
528 |
} |
529 |
if(i < FCGID_REQUEST_SLEEPCOUNT){ |
530 |
wait_msec+=FCGID_REQUEST_SLEEPSIZE; |
531 |
}else{ |
532 |
/* our request count exceeds the FCGID_REQUEST_SLEEPCOUNT |
533 |
* value, so lets give it more priority by lowering the wait |
534 |
* and hopefulle preventing a HTTP_SERVICE_UNAVAILABLE */ |
535 |
wait_msec-=FCGID_REQUEST_SLEEPSIZE; |
536 |
} |
537 |
|
538 |
/* we tried try_spawn times to get a process slot but we |
539 |
* failed. So now try to spawn a new one. */ |
540 |
procmgr_send_spawn_cmd(&fcgi_request, r); |
479 |
} |
541 |
} |
480 |
|
542 |
|
481 |
/* Now I get a connected ipc handle */ |
543 |
/* Now I get a connected ipc handle */ |