You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2005/09/19 14:52:23 UTC

svn commit: r290141 - in /httpd/httpd/branches/2.2.x/modules/proxy: NWGNUproxy ajp.h ajp_header.h mod_proxy.c mod_proxy.h mod_proxy_balancer.c proxy_util.c

Author: jim
Date: Mon Sep 19 05:52:19 2005
New Revision: 290141

URL: http://svn.apache.org/viewcvs?rev=290141&view=rev
Log:
Backport of the following patches from trunk:

  r279973
  r279752
  r279579
  r279319
  r279305

------------------------------------------------------------------------
r279973 | jorton | 2005-09-10 05:10:27 -0400 (Sat, 10 Sep 2005) | 5 lines

* modules/proxy/mod_proxy_balancer.c (balancer_handler): Fix gcc
warning; no functional change.

* modules/proxy/mod_proxy.c (set_balancer_param): Likewise.

------------------------------------------------------------------------
r279752 | jim | 2005-09-09 08:28:02 -0400 (Fri, 09 Sep 2005) | 4 lines

Proxy balancer lbmethods are now registered as providers and not
via hooks. Move various find() functions back to mod_proxy_balancer
where they belong :)

------------------------------------------------------------------------
r279579 | bnicholes | 2005-09-08 12:37:00 -0400 (Thu, 08 Sep 2005) | 1 line

Remove proxy_hook_load_lbmethods from Netware export list

------------------------------------------------------------------------
r279319 | jim | 2005-09-07 09:14:16 -0400 (Wed, 07 Sep 2005) | 2 lines

Minor nit. Methods are server-wide, so simply use the base version table.

------------------------------------------------------------------------
r279305 | jim | 2005-09-07 08:04:15 -0400 (Wed, 07 Sep 2005) | 4 lines

Restruct of lbmethod find-best algo's, bypassing hook mechanism.
Looking into provider method, but until then... Prevent core dump
when balancer not in vhosts


Modified:
    httpd/httpd/branches/2.2.x/modules/proxy/NWGNUproxy
    httpd/httpd/branches/2.2.x/modules/proxy/ajp.h
    httpd/httpd/branches/2.2.x/modules/proxy/ajp_header.h
    httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.c
    httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
    httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c
    httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c

Modified: httpd/httpd/branches/2.2.x/modules/proxy/NWGNUproxy
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/NWGNUproxy?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/NWGNUproxy (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/NWGNUproxy Mon Sep 19 05:52:19 2005
@@ -229,7 +229,6 @@
 	proxy_hook_canon_handler \
 	proxy_hook_pre_request \
 	proxy_hook_post_request \
-	proxy_hook_load_lbmethods \
 	ap_proxy_ssl_enable \
 	ap_proxy_ssl_disable \
 	ap_proxy_conn_is_https \

Modified: httpd/httpd/branches/2.2.x/modules/proxy/ajp.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/ajp.h?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/ajp.h (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/ajp.h Mon Sep 19 05:52:19 2005
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+/**
+ * @file ajp.h
+ * @brief Apache Jserv Protocol
+ *
+ * @defgroup AJP_defines AJP definitions
+ * @ingroup  MOD_PROXY
+ * @{
+ */
+
 #ifndef AJP_H
 #define AJP_H
 
@@ -126,10 +135,6 @@
 };
 
 /**
- * @defgroup AJP_defines AJP definitions 
- * @{
- */
-/**
  * Signature for the messages sent from Apache to tomcat
  */
 #define AJP13_WS_HEADER             0x1234
@@ -161,6 +166,7 @@
 
 /**
  * @defgroup AJP_api AJP API functions
+ * @ingroup  MOD_PROXY
  * @{
  */
 /**

Modified: httpd/httpd/branches/2.2.x/modules/proxy/ajp_header.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/ajp_header.h?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/ajp_header.h (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/ajp_header.h Mon Sep 19 05:52:19 2005
@@ -13,6 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+/**
+ * @file ajp_header.h
+ * @brief AJP defines
+ *
+ * @addtogroup AJP_defines
+ * @{
+ */
+
 #ifndef AJP_HEADER_H
 #define AJP_HEADER_H
 
@@ -163,3 +172,4 @@
 #define SC_RES_HEADERS_NUM          11
 
 #endif /* AJP_HEADER_H */
+/** @} */

Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.c?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.c Mon Sep 19 05:52:19 2005
@@ -273,15 +273,11 @@
         balancer->max_attempts_set = 1;
     }
     else if (!strcasecmp(key, "lbmethod")) {
-        struct proxy_balancer_method *ent =
-           (struct proxy_balancer_method *) conf->lbmethods->elts;
-        int i;
-        for (i = 0; i < conf->lbmethods->nelts; i++) {
-           if (!strcasecmp(val, ent->name)) {
-               balancer->lbmethod = ent;
-               return NULL;
-           }
-           ent++;
+        proxy_balancer_method *provider;
+        provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
+        if (provider) {
+            balancer->lbmethod = provider;
+            return NULL;
         }
         return "unknown lbmethod";
     }
@@ -798,7 +794,6 @@
     ps->allowed_connect_ports = apr_array_make(p, 10, sizeof(int));
     ps->workers = apr_array_make(p, 10, sizeof(proxy_worker));
     ps->balancers = apr_array_make(p, 10, sizeof(proxy_balancer));
-    ps->lbmethods = apr_array_make(p, 10, sizeof(proxy_balancer_method));
     ps->forward = NULL;
     ps->reverse = NULL;
     ps->domain = NULL;
@@ -821,9 +816,7 @@
     ps->badopt = bad_error;
     ps->badopt_set = 0;
     ps->pool = p;
-    
-    proxy_run_load_lbmethods(ps);
-    
+        
     return ps;
 }
 
@@ -841,7 +834,6 @@
     ps->allowed_connect_ports = apr_array_append(p, base->allowed_connect_ports, overrides->allowed_connect_ports);
     ps->workers = apr_array_append(p, base->workers, overrides->workers);
     ps->balancers = apr_array_append(p, base->balancers, overrides->balancers);
-    ps->lbmethods = apr_array_append(p, base->lbmethods, overrides->lbmethods);
     ps->forward = overrides->forward ? overrides->forward : base->forward;
     ps->reverse = overrides->reverse ? overrides->reverse : base->reverse;
 
@@ -1522,7 +1514,7 @@
             err = set_balancer_param(conf, cmd->pool, balancer, word, val);
 
         if (err)
-            return apr_pstrcat(cmd->temp_pool, "ProxySet ", err, " ", word, " ", name, NULL);
+            return apr_pstrcat(cmd->temp_pool, "ProxySet: ", err, " ", word, "=", val, "; ", name, NULL);
     }
 
     return NULL;
@@ -1925,7 +1917,6 @@
     APR_HOOK_LINK(canon_handler)
     APR_HOOK_LINK(pre_request)
     APR_HOOK_LINK(post_request)
-    APR_HOOK_LINK(load_lbmethods)
     APR_HOOK_LINK(request_status)
 )
 
@@ -1951,10 +1942,6 @@
                                        request_rec *r,
                                        proxy_server_conf *conf),(worker,
                                        balancer,r,conf),DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(proxy, PROXY, int, load_lbmethods,
-                                    (proxy_server_conf *conf), 
-                                    (conf),
-                                    OK, DECLINED)
 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups,
                                     (request_rec *r), (r),
                                     OK, DECLINED)

Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h Mon Sep 19 05:52:19 2005
@@ -17,8 +17,13 @@
 #ifndef MOD_PROXY_H
 #define MOD_PROXY_H 
 
-/*
- * Main include file for the Apache proxy
+/**
+ * @file  mod_proxy.h
+ * @brief Proxy Extension Module for Apache
+ *
+ * @defgroup MOD_PROXY mod_proxy
+ * @ingroup  APACHE_MODS
+ * @{
  */
 
 /*
@@ -68,6 +73,7 @@
 #include "http_connection.h"
 #include "util_filter.h"
 #include "util_ebcdic.h"
+#include "ap_provider.h"
 
 #if APR_HAVE_NETINET_IN_H
 #include <netinet/in.h>
@@ -180,7 +186,6 @@
     } proxy_status;             /* Status display options */
     char proxy_status_set;
     apr_pool_t *pool;           /* Pool used for allocating this struct */
-    apr_array_header_t *lbmethods;
 } proxy_server_conf;
 
 
@@ -374,14 +379,6 @@
 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r)) 
 
-/*
- * Useful hook run within the create per-server phase which
- * adds the required lbmethod structs, so they exist at
- * configure time
- */
-APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, load_lbmethods,
-                                     (proxy_server_conf *conf))
-
 /**
  * pre request hook.
  * It will return the most suitable worker at the moment
@@ -680,6 +677,8 @@
 #define PROXY_HAS_SCOREBOARD 0
 #endif
 
+#define PROXY_LBMETHOD "proxylbmethod"
+
 /* The number of dynamic workers that can be added when reconfiguring.
  * If this limit is reached you must stop and restart the server.
  */
@@ -696,3 +695,4 @@
 extern int PROXY_DECLARE_DATA proxy_lb_workers;
 
 #endif /*MOD_PROXY_H*/
+/** @} */

Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c Mon Sep 19 05:52:19 2005
@@ -218,147 +218,6 @@
         return NULL;
 }
 
-/*
- * The idea behind the find_best_byrequests scheduler is the following:
- *
- * lbfactor is "how much we expect this worker to work", or "the worker's
- * normalized work quota".
- *
- * lbstatus is "how urgent this worker has to work to fulfill its quota
- * of work".
- *
- * We distribute each worker's work quota to the worker, and then look
- * which of them needs to work most urgently (biggest lbstatus).  This
- * worker is then selected for work, and its lbstatus reduced by the
- * total work quota we distributed to all workers.  Thus the sum of all
- * lbstatus does not change.(*)
- *
- * If some workers are disabled, the others will
- * still be scheduled correctly.
- *
- * If a balancer is configured as follows:
- *
- * worker     a    b    c    d
- * lbfactor  25   25   25   25
- *
- * And b gets disabled, the following schedule is produced:
- *
- *    a c d a c d a c d ...
- *
- * Note that the above lbfactor setting is the *exact* same as:
- *
- * worker     a    b    c    d
- * lbfactor   1    1    1    1
- *
- * Asymmetric configurations work as one would expect. For
- * example:
- *
- * worker     a    b    c    d
- * lbfactor   1    1    1    2
- *
- * would have a, b and c all handling about the same
- * amount of load with d handling twice what a or b
- * or c handles individually. So we could see:
- *
- *   b a d c d a c d b d ...
- *
- */
- 
-static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
-                                request_rec *r)
-{
-    int i;
-    int total_factor = 0;
-    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
-    proxy_worker *mycandidate = NULL;
-    
-    /* First try to see if we have available candidate */
-    for (i = 0; i < balancer->workers->nelts; i++) {
-        /* If the worker is in error state run
-         * retry on that worker. It will be marked as
-         * operational if the retry timeout is elapsed.
-         * The worker might still be unusable, but we try
-         * anyway.
-         */
-        if (!PROXY_WORKER_IS_USABLE(worker))
-            ap_proxy_retry_worker("BALANCER", worker, r->server);
-        /* Take into calculation only the workers that are
-         * not in error state or not disabled.
-         */
-        if (PROXY_WORKER_IS_USABLE(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++;
-    }
-
-    return mycandidate;
-}
-
-/*
- * The idea behind the find_best_bytraffic scheduler is the following:
- *
- * We know the amount of traffic (bytes in and out) handled by each
- * worker. We normalize that traffic by each workers' weight. So assuming
- * a setup as below:
- *
- * worker     a    b    c
- * lbfactor   1    1    3
- *
- * the scheduler will allow worker c to handle 3 times the
- * traffic of a and b. If each request/response results in the
- * same amount of traffic, then c would be accessed 3 times as
- * often as a or b. If, for example, a handled a request that
- * resulted in a large i/o bytecount, then b and c would be
- * chosen more often, to even things out.
- */
-static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
-                                         request_rec *r)
-{
-    int i;
-    apr_off_t mytraffic = 0;
-    apr_off_t curmin = 0;
-    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
-    proxy_worker *mycandidate = NULL;
-    
-    /* First try to see if we have available candidate */
-    for (i = 0; i < balancer->workers->nelts; i++) {
-        /* If the worker is in error state run
-         * retry on that worker. It will be marked as
-         * operational if the retry timeout is elapsed.
-         * The worker might still be unusable, but we try
-         * anyway.
-         */
-        if (!PROXY_WORKER_IS_USABLE(worker))
-            ap_proxy_retry_worker("BALANCER", worker, r->server);
-        /* Take into calculation only the workers that are
-         * not in error state or not disabled.
-         */
-        if (PROXY_WORKER_IS_USABLE(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++;
-    }
-
-    return mycandidate;
-}
-
 static proxy_worker *find_best_worker(proxy_balancer *balancer,
                                       request_rec *r)
 {
@@ -657,15 +516,10 @@
             bsel->max_attempts_set = 1;
         }
         if ((val = apr_table_get(params, "lm"))) {
-            struct proxy_balancer_method *ent =
-               (struct proxy_balancer_method *) conf->lbmethods->elts;
-            int i;
-            for (i = 0; i < conf->lbmethods->nelts; i++) {
-                if (!strcasecmp(val, ent->name)) {
-                    bsel->lbmethod = ent;
-                    break;
-                }
-                ent++;
+            proxy_balancer_method *provider;
+            provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
+            if (provider) {
+                bsel->lbmethod = provider;
             }
         }
     }
@@ -836,14 +690,16 @@
                        bsel->max_attempts);
             ap_rputs("<tr><td>LB Method:</td><td><select name=\"lm\">", r);
             {
-                struct proxy_balancer_method *ent =
-                   (struct proxy_balancer_method *) conf->lbmethods->elts;
+                apr_array_header_t *methods;
+                ap_list_provider_names_t *method;
                 int i;
-                for (i = 0; i < conf->lbmethods->nelts; i++) {
-                    ap_rprintf(r, "<option value=\"%s\" %s>%s</option>", ent->name,
-                       (!strcasecmp(bsel->lbmethod->name, ent->name)) ? "selected" : "",
-                       ent->name);
-                    ent++;
+                methods = ap_list_provider_names(r->pool, PROXY_LBMETHOD, "0");
+                method = (ap_list_provider_names_t *)methods->elts;
+                for (i = 0; i < methods->nelts; i++) {
+                    ap_rprintf(r, "<option value=\"%s\" %s>%s</option>", method->provider_name,
+                       (!strcasecmp(bsel->lbmethod->name, method->provider_name)) ? "selected" : "",
+                       method->provider_name);
+                    method++;
                 }
             }
             ap_rputs("</select></td></tr>\n", r);
@@ -880,29 +736,175 @@
 }
 
 /*
- * How to add additional lbmethods:
- *   1. Create func which determines "best" candidate worker
- *      (eg: find_best_bytraffic, above)
- *   2. Create proxy_balancer_method struct which
- *      defines the method and add it to
- *      available server methods using
- *      the proxy_hook_load_lbmethods hook
- *      (eg: add_lbmethods below).
+ * The idea behind the find_best_byrequests scheduler is the following:
+ *
+ * lbfactor is "how much we expect this worker to work", or "the worker's
+ * normalized work quota".
+ *
+ * lbstatus is "how urgent this worker has to work to fulfill its quota
+ * of work".
+ *
+ * We distribute each worker's work quota to the worker, and then look
+ * which of them needs to work most urgently (biggest lbstatus).  This
+ * worker is then selected for work, and its lbstatus reduced by the
+ * total work quota we distributed to all workers.  Thus the sum of all
+ * lbstatus does not change.(*)
+ *
+ * If some workers are disabled, the others will
+ * still be scheduled correctly.
+ *
+ * If a balancer is configured as follows:
+ *
+ * worker     a    b    c    d
+ * lbfactor  25   25   25   25
+ *
+ * And b gets disabled, the following schedule is produced:
+ *
+ *    a c d a c d a c d ...
+ *
+ * Note that the above lbfactor setting is the *exact* same as:
+ *
+ * worker     a    b    c    d
+ * lbfactor   1    1    1    1
+ *
+ * Asymmetric configurations work as one would expect. For
+ * example:
+ *
+ * worker     a    b    c    d
+ * lbfactor   1    1    1    2
+ *
+ * would have a, b and c all handling about the same
+ * amount of load with d handling twice what a or b
+ * or c handles individually. So we could see:
+ *
+ *   b a d c d a c d b d ...
+ *
  */
-static int add_lbmethods(proxy_server_conf *conf)
+ 
+static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
+                                request_rec *r)
 {
-    proxy_balancer_method *new;
+    int i;
+    int total_factor = 0;
+    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
+    proxy_worker *mycandidate = NULL;
+ 
 
-    new  = apr_array_push(conf->lbmethods);
-    new->name = "byrequests";
-    new->finder = find_best_byrequests;
-    new  = apr_array_push(conf->lbmethods);
-    new->name = "bytraffic";
-    new->finder = find_best_bytraffic;
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                 "proxy: Entering byrequests for BALANCER (%s)",
+                 balancer->name);
 
-    return OK;
+    /* First try to see if we have available candidate */
+    for (i = 0; i < balancer->workers->nelts; i++) {
+        /* If the worker is in error state run
+         * retry on that worker. It will be marked as
+         * operational if the retry timeout is elapsed.
+         * The worker might still be unusable, but we try
+         * anyway.
+         */
+        if (!PROXY_WORKER_IS_USABLE(worker))
+            ap_proxy_retry_worker("BALANCER", worker, r->server);
+        /* Take into calculation only the workers that are
+         * not in error state or not disabled.
+         */
+        if (PROXY_WORKER_IS_USABLE(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++;
+    }
+
+    return mycandidate;
 }
 
+/*
+ * The idea behind the find_best_bytraffic scheduler is the following:
+ *
+ * We know the amount of traffic (bytes in and out) handled by each
+ * worker. We normalize that traffic by each workers' weight. So assuming
+ * a setup as below:
+ *
+ * worker     a    b    c
+ * lbfactor   1    1    3
+ *
+ * the scheduler will allow worker c to handle 3 times the
+ * traffic of a and b. If each request/response results in the
+ * same amount of traffic, then c would be accessed 3 times as
+ * often as a or b. If, for example, a handled a request that
+ * resulted in a large i/o bytecount, then b and c would be
+ * chosen more often, to even things out.
+ */
+static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
+                                         request_rec *r)
+{
+    int i;
+    apr_off_t mytraffic = 0;
+    apr_off_t curmin = 0;
+    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
+    proxy_worker *mycandidate = NULL;
+    
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                 "proxy: Entering bytraffic for BALANCER (%s)",
+                 balancer->name);
+
+    /* First try to see if we have available candidate */
+    for (i = 0; i < balancer->workers->nelts; i++) {
+        /* If the worker is in error state run
+         * retry on that worker. It will be marked as
+         * operational if the retry timeout is elapsed.
+         * The worker might still be unusable, but we try
+         * anyway.
+         */
+        if (!PROXY_WORKER_IS_USABLE(worker))
+            ap_proxy_retry_worker("BALANCER", worker, r->server);
+        /* Take into calculation only the workers that are
+         * not in error state or not disabled.
+         */
+        if (PROXY_WORKER_IS_USABLE(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++;
+    }
+
+    return mycandidate;
+}
+
+/*
+ * How to add additional lbmethods:
+ *   1. Create func which determines "best" candidate worker
+ *      (eg: find_best_bytraffic, above)
+ *   2. Register it as a provider.
+ */
+static const proxy_balancer_method byrequests =
+{
+    "byrequests",
+    &find_best_byrequests,
+    NULL
+};
+
+static const proxy_balancer_method bytraffic =
+{
+    "bytraffic",
+    &find_best_bytraffic,
+    NULL
+};
+
 static void ap_proxy_balancer_register_hook(apr_pool_t *p)
 {
     /* Only the mpm_winnt has child init hook handler.
@@ -916,7 +918,8 @@
     proxy_hook_pre_request(proxy_balancer_pre_request, NULL, NULL, APR_HOOK_FIRST);    
     proxy_hook_post_request(proxy_balancer_post_request, NULL, NULL, APR_HOOK_FIRST);    
     proxy_hook_canon_handler(proxy_balancer_canon, NULL, NULL, APR_HOOK_FIRST);
-    proxy_hook_load_lbmethods(add_lbmethods, NULL, NULL, APR_HOOK_FIRST);
+    ap_register_provider(p, PROXY_LBMETHOD, "bytraffic", "0", &bytraffic);
+    ap_register_provider(p, PROXY_LBMETHOD, "byrequests", "0", &byrequests);
 }
 
 module AP_MODULE_DECLARE_DATA proxy_balancer_module = {

Modified: httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c?rev=290141&r1=290140&r2=290141&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c Mon Sep 19 05:52:19 2005
@@ -1155,7 +1155,6 @@
                                                   const char *url)
 {
     char *c, *q, *uri = apr_pstrdup(p, url);
-    int i;
     proxy_balancer_method *lbmethod;
 
     c = strchr(uri, ':');   
@@ -1173,12 +1172,9 @@
      * NOTE: The default method is byrequests, which we assume
      * exists!
      */
-    lbmethod = (proxy_balancer_method *)conf->lbmethods->elts;
-    for (i = 0; i < conf->lbmethods->nelts; i++) {
-        if (!strcasecmp(lbmethod->name, "byrequests")) {
-            break;
-        }
-        lbmethod++;
+    lbmethod = ap_lookup_provider(PROXY_LBMETHOD, "byrequests", "0");
+    if (!lbmethod) {
+        return "Can't find 'byrequests' lb method";
     }
 
     (*balancer)->name = uri;