]> granicus.if.org Git - apache/commitdiff
Add force recovery for balancer.
authorMladen Turk <mturk@apache.org>
Sat, 30 Sep 2006 10:18:48 +0000 (10:18 +0000)
committerMladen Turk <mturk@apache.org>
Sat, 30 Sep 2006 10:18:48 +0000 (10:18 +0000)
In case all balancer members were in error state 503
was returned until the recovery timeout expired.
The patch forces recovery in case all balancer members
are in error state regardless of recovery timeout
directive.
This fixes the time gap when 503 was returned and
backend was already up and running.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@451572 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/mod_proxy_balancer.c

index 8870a4a72b140867ea70612e72a46212d47469ea..4204d71206ab0858f6ff5e06278cc3de49ea7fef 100644 (file)
@@ -358,6 +358,33 @@ static int rewrite_url(request_rec *r, proxy_worker *worker,
     return OK;
 }
 
+static void force_recovery(proxy_balancer *balancer, server_rec *s)
+{
+    int i;
+    int ok = 0;
+    proxy_worker *worker;
+
+    worker = (proxy_worker *)balancer->workers->elts;
+    for (i = 0; i < balancer->workers->nelts; i++, worker++) {
+        if (!(worker->s->status & PROXY_WORKER_IN_ERROR)) {
+            ok = 1;
+            break;    
+        }
+    }
+    if (!ok) {
+        /* If all workers are in error state force the recovery.
+         */
+        worker = (proxy_worker *)balancer->workers->elts;
+        for (i = 0; i < balancer->workers->nelts; i++, worker++) {
+            ++worker->s->retries;
+            worker->s->status &= ~PROXY_WORKER_IN_ERROR;
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                         "proxy: BALANCER: (%s). Forcing recovery for worker (%s)",
+                         balancer->name, worker->hostname);
+        }
+    }
+}
+
 static int proxy_balancer_pre_request(proxy_worker **worker,
                                       proxy_balancer **balancer,
                                       request_rec *r,
@@ -378,17 +405,21 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
         !(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))
         return DECLINED;
 
-    /* Step 2: find the session route */
-
-    runtime = find_session_route(*balancer, r, &route, url);
-    /* Lock the LoadBalancer
+    /* Step 2: Lock the LoadBalancer
      * XXX: perhaps we need the process lock here
      */
     if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
-                     "proxy: BALANCER: lock");
+                     "proxy: BALANCER: (%s). Lock",
+                     (*balancer)->name);
         return DECLINED;
     }
+
+    /* Step 3: force recovery */
+    force_recovery(*balancer, r->server);
+
+    /* Step 4: find the session route */
+    runtime = find_session_route(*balancer, r, &route, url);
     if (runtime) {
         int i, total_factor = 0;
         proxy_worker *workers;