From: Daniel Ruggeri Date: Tue, 9 Apr 2013 00:18:42 +0000 (+0000) Subject: Add failontimeout to allow server admin to mark balancer member in err if IO timeout... X-Git-Tag: 2.5.0-alpha~5610 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d31632f33cf0975b0b4b347d22dbc0d67b06268e;p=apache Add failontimeout to allow server admin to mark balancer member in err if IO timeout occurs. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1465839 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 1db299c003..ea5f1c5174 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -2460 +2461 diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml index 1288423308..4de2cb28e9 100644 --- a/docs/manual/mod/mod_proxy.xml +++ b/docs/manual/mod/mod_proxy.xml @@ -1138,6 +1138,12 @@ ProxyPass /mirror/foo http://backend.example.com force the worker into error state when the backend returns any status code in the list. Worker recovery behaves the same as other worker errors. + failontimeout + Off + If set, an IO read timeout after a request is sent to the backend will + force the worker into error state. Worker recovery behaves the same as other + worker errors. + nonce <auto> The protective nonce used in the balancer-manager application page. diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index b5ff09bbc4..58cbfb8315 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -383,6 +383,14 @@ static const char *set_balancer_param(proxy_server_conf *conf, } } + else if (!strcasecmp(key, "failontimeout")) { + if (!strcasecmp(val, "on")) + balancer->failontimeout = 1; + else if (!strcasecmp(val, "off")) + balancer->failontimeout = 0; + else + return "failontimeout must be On|Off"; + } else if (!strcasecmp(key, "nonce")) { if (!strcasecmp(val, "None")) { *balancer->s->nonce = '\0'; diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index a6ab92cc76..43835b1b76 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -451,6 +451,7 @@ struct proxy_balancer { proxy_server_conf *sconf; void *context; /* general purpose storage */ proxy_balancer_shared *s; /* Shared data */ + int failontimeout; /* Whether to mark a member in Err if IO timeout occurs */ }; struct proxy_balancer_method { diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index e796f73b5e..46cda6ed10 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -662,6 +662,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, * but doesn't affect the whole worker. */ if (APR_STATUS_IS_TIMEUP(status) && conn->worker->s->ping_timeout_set) { + apr_table_set(r->notes, "proxy_timedout", "1"); rv = HTTP_GATEWAY_TIME_OUT; } else { diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index cd9987e192..b1fd84eeb5 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -649,6 +649,17 @@ static int proxy_balancer_post_request(proxy_worker *worker, } } + if (balancer->failontimeout + && (apr_table_get(r->notes, "proxy_timedout")) != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02460) + "%s: Forcing worker (%s) into error state " + "due to timeout and 'failonstatus' parameter being set", + balancer->s->name, worker->s->name); + worker->s->status |= PROXY_WORKER_IN_ERROR; + worker->s->error_time = apr_time_now(); + + } + if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01175) "%s: Unlock failed for post_request", balancer->s->name); diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 543afada51..0712b61d5f 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -1312,6 +1312,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, "error reading status line from remote " "server %s:%d", backend->hostname, backend->port); if (APR_STATUS_IS_TIMEUP(rc)) { + apr_table_set(r->notes, "proxy_timedout", "1"); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01103) "read timeout"); if (do_100_continue) { return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, "Timeout on 100-Continue");