File httpd-2.2.x-bnc789828-mod_balancer.diff of Package apache2
diff -rNU 20 ../httpd-2.2.21-o/modules/proxy/mod_proxy_balancer.c ./modules/proxy/mod_proxy_balancer.c
--- ../httpd-2.2.21-o/modules/proxy/mod_proxy_balancer.c 2010-10-07 20:51:18.000000000 +0200
+++ ./modules/proxy/mod_proxy_balancer.c 2013-01-28 14:19:44.000000000 +0100
@@ -414,40 +414,52 @@
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 apr_status_t decrement_busy_count(void *worker_)
+{
+ proxy_worker *worker = worker_;
+
+ if (worker->s->busy) {
+ worker->s->busy--;
+ }
+
+ return APR_SUCCESS;
+}
+
static int proxy_balancer_pre_request(proxy_worker **worker,
proxy_balancer **balancer,
request_rec *r,
proxy_server_conf *conf, char **url)
{
int access_status;
proxy_worker *runtime;
char *route = NULL;
char *sticky = NULL;
apr_status_t rv;
*worker = NULL;
/* Step 1: check if the url is for us
* The url we can handle starts with 'balancer://'
* If balancer is already provided skip the search
* for balancer, because this is failover attempt.
*/
if (!*balancer &&
!(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))
return DECLINED;
@@ -536,40 +548,44 @@
(*balancer)->name);
return HTTP_SERVICE_UNAVAILABLE;
}
if ((*balancer)->sticky && runtime) {
/*
* This balancer has sticky sessions and the client either has not
* supplied any routing information or all workers for this route
* including possible redirect and hotstandby workers are in error
* state, but we have found another working worker for this
* balancer where we can send the request. Thus notice that we have
* changed the route to the backend.
*/
apr_table_setn(r->subprocess_env, "BALANCER_ROUTE_CHANGED", "1");
}
*worker = runtime;
}
(*worker)->s->busy++;
+ apr_pool_cleanup_register(r->pool, *worker, decrement_busy_count,
+ apr_pool_cleanup_null);
+
+
/* Add balancer/worker info to env. */
apr_table_setn(r->subprocess_env,
"BALANCER_NAME", (*balancer)->name);
apr_table_setn(r->subprocess_env,
"BALANCER_WORKER_NAME", (*worker)->name);
apr_table_setn(r->subprocess_env,
"BALANCER_WORKER_ROUTE", (*worker)->s->route);
/* Rewrite the url from 'balancer://url'
* to the 'worker_scheme://worker_hostname[:worker_port]/url'
* This replaces the balancers fictional name with the
* real hostname of the elected worker.
*/
access_status = rewrite_url(r, *worker, url);
/* Add the session route to request notes if present */
if (route) {
apr_table_setn(r->notes, "session-sticky", sticky);
apr_table_setn(r->notes, "session-route", route);
/* Add session info to env. */
@@ -605,43 +621,40 @@
int val = ((int *)balancer->errstatuses->elts)[i];
if (r->status == val) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
"proxy: BALANCER: (%s). Forcing recovery for worker (%s), failonstatus %d",
balancer->name, worker->name, val);
worker->s->status |= PROXY_WORKER_IN_ERROR;
worker->s->error_time = apr_time_now();
break;
}
}
}
if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
"proxy: BALANCER: (%s). Unlock failed for post_request",
balancer->name);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy_balancer_post_request for (%s)", balancer->name);
- if (worker && worker->s->busy)
- worker->s->busy--;
-
return OK;
}
static void recalc_factors(proxy_balancer *balancer)
{
int i;
proxy_worker *workers;
/* Recalculate lbfactors */
workers = (proxy_worker *)balancer->workers->elts;
/* Special case if there is only one worker it's
* load factor will always be 1
*/
if (balancer->workers->nelts == 1) {
workers->s->lbstatus = workers->s->lbfactor = 1;
return;
}
for (i = 0; i < balancer->workers->nelts; i++) {