From: Graham Leggett Date: Fri, 2 Dec 2011 22:42:39 +0000 (+0000) Subject: mod_proxy: Make ap_proxy_retry_worker() into an optional function. Allows X-Git-Tag: 2.5.0-alpha~7749 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0182b1654f065b6770f41479aa2128be534e6d06;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy: Make ap_proxy_retry_worker() into an optional function. Allows mod_lbmethod_bybusyness, mod_lbmethod_byrequests, mod_lbmethod_bytraffic and mod_lbmethod_heartbeat to be loaded without mod_proxy yet being present, which happens when modules are loaded in alphabetical order. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1209754 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/balancers/mod_lbmethod_bybusyness.c b/modules/proxy/balancers/mod_lbmethod_bybusyness.c index 9dd246bd9d0..2b3124e25c8 100644 --- a/modules/proxy/balancers/mod_lbmethod_bybusyness.c +++ b/modules/proxy/balancers/mod_lbmethod_bybusyness.c @@ -22,6 +22,9 @@ module AP_MODULE_DECLARE_DATA lbmethod_bybusyness_module; +static int (*ap_proxy_retry_worker_fn)(const char *proxy_function, + proxy_worker *worker, server_rec *s) = NULL; + static proxy_worker *find_best_bybusyness(proxy_balancer *balancer, request_rec *r) { @@ -36,6 +39,15 @@ static proxy_worker *find_best_bybusyness(proxy_balancer *balancer, int total_factor = 0; + if (!ap_proxy_retry_worker_fn) { + ap_proxy_retry_worker_fn = + APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker); + if (!ap_proxy_retry_worker_fn) { + /* can only happen if mod_proxy isn't loaded */ + return NULL; + } + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: Entering bybusyness for BALANCER (%s)", balancer->s->name); @@ -66,8 +78,9 @@ static proxy_worker *find_best_bybusyness(proxy_balancer *balancer, * The worker might still be unusable, but we try * anyway. */ - if (!PROXY_WORKER_IS_USABLE(*worker)) - ap_proxy_retry_worker("BALANCER", *worker, r->server); + if (!PROXY_WORKER_IS_USABLE(*worker)) { + ap_proxy_retry_worker_fn("BALANCER", *worker, r->server); + } /* Take into calculation only the workers that are * not in error state or not disabled. diff --git a/modules/proxy/balancers/mod_lbmethod_byrequests.c b/modules/proxy/balancers/mod_lbmethod_byrequests.c index 9cc3bba71ff..0efa81d70a0 100644 --- a/modules/proxy/balancers/mod_lbmethod_byrequests.c +++ b/modules/proxy/balancers/mod_lbmethod_byrequests.c @@ -22,6 +22,9 @@ module AP_MODULE_DECLARE_DATA lbmethod_byrequests_module; +static int (*ap_proxy_retry_worker_fn)(const char *proxy_function, + proxy_worker *worker, server_rec *s) = NULL; + /* * The idea behind the find_best_byrequests scheduler is the following: * @@ -80,6 +83,15 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer, int checking_standby; int checked_standby; + if (!ap_proxy_retry_worker_fn) { + ap_proxy_retry_worker_fn = + APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker); + if (!ap_proxy_retry_worker_fn) { + /* can only happen if mod_proxy isn't loaded */ + return NULL; + } + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: Entering byrequests for BALANCER (%s)", balancer->s->name); @@ -109,7 +121,7 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer, * anyway. */ if (!PROXY_WORKER_IS_USABLE(*worker)) - ap_proxy_retry_worker("BALANCER", *worker, r->server); + ap_proxy_retry_worker_fn("BALANCER", *worker, r->server); /* Take into calculation only the workers that are * not in error state or not disabled. */ diff --git a/modules/proxy/balancers/mod_lbmethod_bytraffic.c b/modules/proxy/balancers/mod_lbmethod_bytraffic.c index d91bec0c0de..ef15dee0d40 100644 --- a/modules/proxy/balancers/mod_lbmethod_bytraffic.c +++ b/modules/proxy/balancers/mod_lbmethod_bytraffic.c @@ -22,6 +22,9 @@ module AP_MODULE_DECLARE_DATA lbmethod_bytraffic_module; +static int (*ap_proxy_retry_worker_fn)(const char *proxy_function, + proxy_worker *worker, server_rec *s) = NULL; + /* * The idea behind the find_best_bytraffic scheduler is the following: * @@ -52,6 +55,15 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer, int checking_standby; int checked_standby; + if (!ap_proxy_retry_worker_fn) { + ap_proxy_retry_worker_fn = + APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker); + if (!ap_proxy_retry_worker_fn) { + /* can only happen if mod_proxy isn't loaded */ + return NULL; + } + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: Entering bytraffic for BALANCER (%s)", balancer->s->name); @@ -81,7 +93,7 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer, * anyway. */ if (!PROXY_WORKER_IS_USABLE(*worker)) - ap_proxy_retry_worker("BALANCER", *worker, r->server); + ap_proxy_retry_worker_fn("BALANCER", *worker, r->server); /* Take into calculation only the workers that are * not in error state or not disabled. */ diff --git a/modules/proxy/balancers/mod_lbmethod_heartbeat.c b/modules/proxy/balancers/mod_lbmethod_heartbeat.c index e5b5c27dc4f..407951caa1c 100644 --- a/modules/proxy/balancers/mod_lbmethod_heartbeat.c +++ b/modules/proxy/balancers/mod_lbmethod_heartbeat.c @@ -31,6 +31,9 @@ module AP_MODULE_DECLARE_DATA lbmethod_heartbeat_module; +static int (*ap_proxy_retry_worker_fn)(const char *proxy_function, + proxy_worker *worker, server_rec *s) = NULL; + static const ap_slotmem_provider_t *storage = NULL; static ap_slotmem_instance_t *hm_serversmem = NULL; @@ -270,6 +273,15 @@ static proxy_worker *find_best_hb(proxy_balancer *balancer, ap_get_module_config(r->server->module_config, &lbmethod_heartbeat_module); + if (!ap_proxy_retry_worker_fn) { + ap_proxy_retry_worker_fn = + APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker); + if (!ap_proxy_retry_worker_fn) { + /* can only happen if mod_proxy isn't loaded */ + return NULL; + } + } + apr_pool_create(&tpool, r->pool); servers = apr_hash_make(tpool); @@ -297,7 +309,7 @@ static proxy_worker *find_best_hb(proxy_balancer *balancer, } if (!PROXY_WORKER_IS_USABLE(*worker)) { - ap_proxy_retry_worker("BALANCER", *worker, r->server); + ap_proxy_retry_worker_fn("BALANCER", *worker, r->server); } if (PROXY_WORKER_IS_USABLE(*worker)) { diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 8e90c9e340a..16df3a1710a 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -19,6 +19,7 @@ #include "apr_optional.h" #include "scoreboard.h" #include "mod_status.h" +#include "proxy_util.h" #if (MODULE_MAGIC_NUMBER_MAJOR > 20020903) #include "mod_ssl.h" @@ -2512,6 +2513,8 @@ static void register_hooks(apr_pool_t *p) /* child init handling */ ap_hook_child_init(child_init, aszPred, NULL, APR_HOOK_MIDDLE); + /* register optional functions within proxy_util.c */ + proxy_util_register_hooks(p); } AP_DECLARE_MODULE(proxy) = diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 04379e73623..1ea2ea86c94 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -27,6 +27,7 @@ */ #include "apr_hooks.h" +#include "apr_optional.h" #include "apr.h" #include "apr_lib.h" #include "apr_strings.h" @@ -769,9 +770,8 @@ PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, * @note The error status of the worker will cleared if the retry interval has * elapsed since the last error. */ -PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function, - proxy_worker *worker, - server_rec *s); +APR_DECLARE_OPTIONAL_FN(int, ap_proxy_retry_worker, + (const char *proxy_function, proxy_worker *worker, server_rec *s)); /** * Acquire a connection from worker connection pool diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index d19e8c9c843..d88a8bb2df9 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -28,6 +28,9 @@ ap_slotmem_provider_t *storage = NULL; module AP_MODULE_DECLARE_DATA proxy_balancer_module; +static int (*ap_proxy_retry_worker_fn)(const char *proxy_function, + proxy_worker *worker, server_rec *s) = NULL; + /* * Register our mutex type before the config is read so we * can adjust the mutex settings using the Mutex directive. @@ -224,7 +227,7 @@ static proxy_worker *find_route_worker(proxy_balancer *balancer, * The worker might still be unusable, but we try * anyway. */ - ap_proxy_retry_worker("BALANCER", worker, r->server); + ap_proxy_retry_worker_fn("BALANCER", worker, r->server); if (PROXY_WORKER_IS_USABLE(worker)) { return worker; } else { @@ -248,7 +251,7 @@ static proxy_worker *find_route_worker(proxy_balancer *balancer, * The worker might still be unusable, but we try * anyway. */ - ap_proxy_retry_worker("BALANCER", rworker, r->server); + ap_proxy_retry_worker_fn("BALANCER", rworker, r->server); } if (rworker && PROXY_WORKER_IS_USABLE(rworker)) return rworker; @@ -413,7 +416,7 @@ static void force_recovery(proxy_balancer *balancer, server_rec *s) } else { /* Try if we can recover */ - ap_proxy_retry_worker("BALANCER", *worker, s); + ap_proxy_retry_worker_fn("BALANCER", *worker, s); if (!((*worker)->s->status & PROXY_WORKER_IN_ERROR)) { ok = 1; break; @@ -696,8 +699,19 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, /* balancer_post_config() will be called twice during startup. So, don't * set up the static data the 1st time through. */ - if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) + if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) { return OK; + } + + if (!ap_proxy_retry_worker_fn) { + ap_proxy_retry_worker_fn = + APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker); + if (!ap_proxy_retry_worker_fn) { + ap_log_error( + APLOG_MARK, APLOG_EMERG, 0, s, "mod_proxy must be loaded for mod_proxy_balancer"); + return !OK; + } + } /* * Get slotmem setups diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 6d33930bca8..79d8e15dabe 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -20,6 +20,7 @@ #include "scoreboard.h" #include "apr_version.h" #include "apr_hash.h" +#include "proxy_util.h" #if APR_HAVE_UNISTD_H #include /* for getpid() */ @@ -1977,9 +1978,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser return rv; } -PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function, - proxy_worker *worker, - server_rec *s) +static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worker, + server_rec *s) { if (worker->s->status & PROXY_WORKER_IN_ERROR) { if (apr_time_now() > worker->s->error_time + worker->s->retry) { @@ -3024,3 +3024,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec return APR_SUCCESS; } +void proxy_util_register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker); +} diff --git a/modules/proxy/proxy_util.h b/modules/proxy/proxy_util.h new file mode 100644 index 00000000000..ac332e4d828 --- /dev/null +++ b/modules/proxy/proxy_util.h @@ -0,0 +1,36 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PROXY_UTIL_H_ +#define PROXY_UTIL_H_ + +/** + * @file proxy_util.h + * @brief Internal interfaces private to mod_proxy. + * + * @defgroup MOD_PROXY_PRIVATE Private + * @ingroup MOD_PROXY + * @{ + */ + +/** + * Register optional functions declared within proxy_util.c. + */ +void proxy_util_register_hooks(apr_pool_t *p); + +/** @} */ + +#endif /* PROXY_UTIL_H_ */