Commit 75148725 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

It never fails. I sit on a patch for awhile and

it's not until almost right after I commit it that
I think "hey, there's a better way to do that."
Anyway, I was never happy about the code
duplication of the primary/standby checks...
This fixes that.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@421283 13f79535-47bb-0310-9956-ffa450edef68
parent a006d223
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -260,14 +260,6 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
  PROXY_WORKER_HOT_STANDBY )

#define PROXY_WORKER_IS_USABLE(f)   ( !((f)->s->status & \
  (PROXY_WORKER_NOT_USABLE_BITMAP | PROXY_WORKER_HOT_STANDBY )) && \
  PROXY_WORKER_IS_INITIALIZED(f) )

#define PROXY_WORKER_IS_USABLE_STANDBY(f)   ( !((f)->s->status & \
  PROXY_WORKER_NOT_USABLE_BITMAP) && PROXY_WORKER_IS_STANDBY(f) && \
  PROXY_WORKER_IS_INITIALIZED(f) )

#define PROXY_WORKER_IS_USABLE_DC(f)   ( !((f)->s->status & \
  (PROXY_WORKER_NOT_USABLE_BITMAP)) && PROXY_WORKER_IS_INITIALIZED(f) )

/* default worker retry timeout in seconds */
+106 −151
Original line number Diff line number Diff line
@@ -179,8 +179,15 @@ static proxy_worker *find_route_worker(proxy_balancer *balancer,
                                       const char *route, request_rec *r)
{
    int i;
    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
    for (i = 0; i < balancer->workers->nelts; i++) {
    int checking_standby = 0;
    int checked_standby = 0;
    
    proxy_worker *worker;
    while (!checked_standby) {
        worker = (proxy_worker *)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
                continue;
            if (*(worker->s->route) && strcmp(worker->s->route, route) == 0) {
                if (worker && PROXY_WORKER_IS_USABLE(worker)) {
                    return worker;
@@ -224,35 +231,8 @@ static proxy_worker *find_route_worker(proxy_balancer *balancer,
                    }
                }
            }
        worker++;
        }
    /*
     * Check for any hot-standbys, since we have no usable workers
     */
    worker = (proxy_worker *)balancer->workers->elts;
    for (i = 0; i < balancer->workers->nelts; i++) {
        if (*(worker->s->route) && (strcmp(worker->s->route, route) == 0) &&
            PROXY_WORKER_IS_STANDBY(worker)) {
            if (worker && PROXY_WORKER_IS_USABLE_STANDBY(worker)) {
                return worker;
            } else {
                ap_proxy_retry_worker("BALANCER", worker, r->server);
                if (PROXY_WORKER_IS_USABLE_STANDBY(worker)) {
                        return worker;
                } else {
                    if (*worker->s->redirect) {
                        proxy_worker *rworker = NULL;
                        rworker = find_route_worker(balancer, worker->s->redirect, r);
                        if (rworker && !PROXY_WORKER_IS_USABLE_STANDBY(rworker)) {
                            ap_proxy_retry_worker("BALANCER", rworker, r->server);
                        }
                        if (rworker && PROXY_WORKER_IS_USABLE_STANDBY(rworker))
                            return rworker;
                    }
                }
            }
        }
        worker++;
        checked_standby = checking_standby++;
    }
    return NULL;
}
@@ -718,9 +698,6 @@ static int balancer_handler(request_rec *r)
                ap_rvputs(r, "<td>", worker->s->route, NULL);
                ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
                ap_rprintf(r, "</td><td>%d</td><td>", worker->s->lbfactor);
                if (PROXY_WORKER_IS_USABLE(worker))
                    ap_rputs("Ok", r);
                else {
                if (worker->s->status & PROXY_WORKER_DISABLED)
                   ap_rputs("Dis ", r);
                if (worker->s->status & PROXY_WORKER_IN_ERROR)
@@ -729,9 +706,10 @@ static int balancer_handler(request_rec *r)
                   ap_rputs("Stop ", r);
                if (worker->s->status & PROXY_WORKER_HOT_STANDBY)
                   ap_rputs("Stby ", r);
                if (PROXY_WORKER_IS_USABLE(worker))
                    ap_rputs("Ok", r);
                if (!PROXY_WORKER_IS_INITIALIZED(worker))
                    ap_rputs("-", r);
                }
                ap_rputs("</td></tr>\n", r);

                ++worker;
@@ -880,16 +858,21 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
{
    int i;
    int total_factor = 0;
    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
    proxy_worker *worker;
    proxy_worker *mycandidate = NULL;

    int checking_standby = 0;
    int checked_standby = 0;
    
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "proxy: Entering byrequests for BALANCER (%s)",
                 balancer->name);

    /* First try to see if we have available candidate */
    for (i = 0; i < balancer->workers->nelts; i++) {
    while (!mycandidate && !checked_standby) {
        worker = (proxy_worker *)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
                continue;
            /* If the worker is in error state run
             * retry on that worker. It will be marked as
             * operational if the retry timeout is elapsed.
@@ -907,24 +890,8 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
                if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus)
                    mycandidate = worker;
            }
        worker++;
    }

    if (!mycandidate) {
        worker = (proxy_worker *)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++) {
            if (PROXY_WORKER_IS_STANDBY(worker)) {
                if (!PROXY_WORKER_IS_USABLE_STANDBY(worker))
                    ap_proxy_retry_worker("BALANCER", worker, r->server);
                if (PROXY_WORKER_IS_USABLE_STANDBY(worker)) {
                    worker->s->lbstatus += worker->s->lbfactor;
                    total_factor += worker->s->lbfactor;
                    if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus)
                        mycandidate = worker;
                }
            }
            worker++;
        }
        checked_standby = checking_standby++;
    }

    if (mycandidate) {
@@ -958,7 +925,9 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
    int i;
    apr_off_t mytraffic = 0;
    apr_off_t curmin = 0;
    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
    proxy_worker *worker;
    int checking_standby = 0;
    int checked_standby = 0;
    proxy_worker *mycandidate = NULL;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
@@ -966,7 +935,11 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
                 balancer->name);

    /* First try to see if we have available candidate */
    for (i = 0; i < balancer->workers->nelts; i++) {
    while (!mycandidate && !checked_standby) {
        worker = (proxy_worker *)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
            if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
                continue;
            /* If the worker is in error state run
             * retry on that worker. It will be marked as
             * operational if the retry timeout is elapsed.
@@ -986,26 +959,8 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
                    curmin = mytraffic;
                }
            }
        worker++;
    }

    if (!mycandidate) {
        worker = (proxy_worker *)balancer->workers->elts;
        for (i = 0; i < balancer->workers->nelts; i++) {
            if (PROXY_WORKER_IS_STANDBY(worker)) {
                if (!PROXY_WORKER_IS_USABLE_STANDBY(worker))
                    ap_proxy_retry_worker("BALANCER", worker, r->server);
                if (PROXY_WORKER_IS_USABLE_STANDBY(worker)) {
                    mytraffic = (worker->s->transferred/worker->s->lbfactor) +
                        (worker->s->read/worker->s->lbfactor);
                    if (!mycandidate || mytraffic < curmin) {
                        mycandidate = worker;
                        curmin = mytraffic;
                    }
                }
            }
            worker++;
        }
        checked_standby = checking_standby++;
    }

    if (mycandidate) {
+3 −3
Original line number Diff line number Diff line
@@ -1764,11 +1764,11 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
{
    apr_status_t rv;

    if (!PROXY_WORKER_IS_USABLE_DC(worker)) {
    if (!PROXY_WORKER_IS_USABLE(worker)) {
        /* Retry the worker */
        ap_proxy_retry_worker(proxy_function, worker, s);

        if (!PROXY_WORKER_IS_USABLE_DC(worker)) {
        if (!PROXY_WORKER_IS_USABLE(worker)) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                         "proxy: %s: disabled connection for (%s)",
                         proxy_function, worker->hostname);
@@ -2074,7 +2074,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
     * Altrough some connections may be alive
     * no further connections to the worker could be made
     */
    if (!connected && PROXY_WORKER_IS_USABLE_DC(worker) &&
    if (!connected && PROXY_WORKER_IS_USABLE(worker) &&
        !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
        worker->s->status |= PROXY_WORKER_IN_ERROR;
        worker->s->error_time = apr_time_now();