diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 4b003c4ea3..a68c8536d1 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -213,8 +213,14 @@ static const char *set_worker_param(apr_pool_t *p,
else
worker->status &= ~PROXY_WORKER_IN_ERROR;
}
+ else if (*v == 'H' || *v == 'h') {
+ if (mode)
+ worker->status |= PROXY_WORKER_HOT_STANDBY;
+ else
+ worker->status &= ~PROXY_WORKER_HOT_STANDBY;
+ }
else {
- return "Unknow status parameter option";
+ return "Unknown status parameter option";
}
}
}
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
index c8d12ca4a4..1346eef255 100644
--- a/modules/proxy/mod_proxy_balancer.c
+++ b/modules/proxy/mod_proxy_balancer.c
@@ -226,6 +226,34 @@ 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++;
+ }
return NULL;
}
@@ -690,14 +718,20 @@ static int balancer_handler(request_rec *r)
ap_rvputs(r, "
", worker->s->route, NULL);
ap_rvputs(r, " | ", worker->s->redirect, NULL);
ap_rprintf(r, " | %d | ", worker->s->lbfactor);
- if (worker->s->status & PROXY_WORKER_DISABLED)
- ap_rputs("Dis", r);
- else if (worker->s->status & PROXY_WORKER_IN_ERROR)
- ap_rputs("Err", r);
- else if (worker->s->status & PROXY_WORKER_INITIALIZED)
+ if (PROXY_WORKER_IS_USABLE(worker))
ap_rputs("Ok", r);
- else
- ap_rputs("-", r);
+ else {
+ if (worker->s->status & PROXY_WORKER_DISABLED)
+ ap_rputs("Dis ", r);
+ if (worker->s->status & PROXY_WORKER_IN_ERROR)
+ ap_rputs("Err ", r);
+ if (worker->s->status & PROXY_WORKER_STOPPED)
+ ap_rputs("Stop ", r);
+ if (worker->s->status & PROXY_WORKER_HOT_STANDBY)
+ ap_rputs("Stby ", r);
+ if (!PROXY_WORKER_IS_INITIALIZED(worker))
+ ap_rputs("-", r);
+ }
ap_rputs(" | \n", r);
++worker;
@@ -876,6 +910,23 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
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++;
+ }
+ }
+
if (mycandidate) {
mycandidate->s->lbstatus -= total_factor;
mycandidate->s->elected++;
@@ -938,6 +989,25 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
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++;
+ }
+ }
+
if (mycandidate) {
mycandidate->s->elected++;
}
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 9f8fea2585..307a96bc2d 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -1764,11 +1764,11 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
{
apr_status_t rv;
- if (!PROXY_WORKER_IS_USABLE(worker)) {
+ if (!PROXY_WORKER_IS_USABLE_DC(worker)) {
/* Retry the worker */
ap_proxy_retry_worker(proxy_function, worker, s);
- if (!PROXY_WORKER_IS_USABLE(worker)) {
+ if (!PROXY_WORKER_IS_USABLE_DC(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(worker) &&
+ if (!connected && PROXY_WORKER_IS_USABLE_DC(worker) &&
!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
worker->s->status |= PROXY_WORKER_IN_ERROR;
worker->s->error_time = apr_time_now();