View | Details | Raw Unified | Return to bug 53693
Collapse All | Expand All

(-)fcgid_bridge.c.1725557 (-16 / +78 lines)
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 */

Return to bug 53693