From: Jim Jagielski Date: Tue, 10 Aug 2010 19:46:58 +0000 (+0000) Subject: Fold in some stuff to allow for matching of workers X-Git-Tag: 2.3.7~23 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c55a15fc2fc7bacd54135ac00e4d0daf9aa034e9;p=apache Fold in some stuff to allow for matching of workers to their actual scoreboard slots, independent of slot ID. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@984188 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_mmn.h b/include/ap_mmn.h index de01feb0ff..cca771548e 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -241,6 +241,8 @@ * 20100719.0 (2.3.7-dev) Add symbol name parameter to ap_add_module and * ap_add_loaded_module. Add ap_find_module_short_name * 20100723.0 (2.3.7-dev) Remove ct_output_filters from core rec + * 20100723.1 (2.3.7-dev) Added ap_proxy_hashfunc() and hash elements to + * proxy worker structs */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 913a7fe321..30459a9f43 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -251,11 +251,13 @@ struct proxy_conn_pool { /* worker status flags */ #define PROXY_WORKER_INITIALIZED 0x0001 #define PROXY_WORKER_IGNORE_ERRORS 0x0002 +#define PROXY_WORKER_DRAIN 0x0004 #define PROXY_WORKER_IN_SHUTDOWN 0x0010 #define PROXY_WORKER_DISABLED 0x0020 #define PROXY_WORKER_STOPPED 0x0040 #define PROXY_WORKER_IN_ERROR 0x0080 #define PROXY_WORKER_HOT_STANDBY 0x0100 +#define PROXY_WORKER_FREE 0x0200 #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR ) @@ -290,6 +292,8 @@ typedef struct { void *context; /* general purpose storage */ apr_size_t busy; /* busyness factor */ int lbset; /* load balancer cluster set */ + unsigned int apr_hash; /* hash #0 of worker name */ + unsigned int our_hash; /* hash #1 of worker name. Why 2? hash collisions. */ } proxy_worker_stat; /* Worker configuration */ @@ -343,6 +347,8 @@ struct proxy_worker { char io_buffer_size_set; char keepalive_set; char disablereuse_set; + unsigned int apr_hash; /* hash #0 of worker name */ + unsigned int our_hash; /* hash #1 of worker name. Why 2? hash collisions. */ }; /* @@ -375,6 +381,7 @@ struct proxy_balancer { apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */ #endif void *context; /* general purpose storage */ + apr_time_t updated; /* timestamp of last update */ }; struct proxy_balancer_method { @@ -796,6 +803,17 @@ PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r, PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r, apr_bucket_brigade *from, apr_bucket_brigade *to); +/** + * Return a hash based on the passed string + * @param str string to produce hash from + * @param method hashing method to use + * @return hash as unsigned int + */ + +typedef enum { PROXY_HASHFUNC_PROXY, PROXY_HASHFUNC_APR } proxy_hash_t; + +PROXY_DECLARE(unsigned int) +ap_proxy_hashfunc(const char *str, proxy_hash_t method); #define PROXY_LBMETHOD "proxylbmethod" diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 444ce64e69..1a53053ed4 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -22,11 +22,17 @@ #include "apr_version.h" #include "apr_hooks.h" #include "apr_uuid.h" +#include "apr_date.h" module AP_MODULE_DECLARE_DATA proxy_balancer_module; static char balancer_nonce[APR_UUID_FORMATTED_LENGTH + 1]; +#if 0 +extern void proxy_update_members(proxy_balancer **balancer, request_rec *r, + proxy_server_conf *conf); +#endif + static int proxy_balancer_canon(request_rec *r, char *url) { char *host, *path; @@ -467,6 +473,10 @@ static int proxy_balancer_pre_request(proxy_worker **worker, /* Step 3: force recovery */ force_recovery(*balancer, r->server); + + /* Step 3.5: Update member list for the balancer */ + /* TODO: Implement as provider! */ + /* proxy_update_members(balancer, r, conf); */ /* Step 4: find the session route */ runtime = find_session_route(*balancer, r, &route, &sticky, url); diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index abc8de4831..ade6b24b94 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -19,6 +19,7 @@ #include "ap_mpm.h" #include "scoreboard.h" #include "apr_version.h" +#include "apr_hash.h" #if APR_HAVE_UNISTD_H #include /* for getpid() */ @@ -1335,6 +1336,7 @@ PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer, (*balancer)->name = uri; (*balancer)->lbmethod = lbmethod; (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *)); + (*balancer)->updated = apr_time_now(); /* XXX Is this a right place to create mutex */ #if APR_HAS_THREADS if (apr_thread_mutex_create(&((*balancer)->mutex), @@ -1471,6 +1473,7 @@ PROXY_DECLARE(const char *) ap_proxy_add_worker_wid(proxy_worker **worker, (*worker)->port = uri.port; if (id < 0) { (*worker)->id = proxy_lb_workers; + /* Increase the total worker count */ proxy_lb_workers++; } else { (*worker)->id = id; @@ -1478,13 +1481,22 @@ PROXY_DECLARE(const char *) ap_proxy_add_worker_wid(proxy_worker **worker, (*worker)->flush_packets = flush_off; (*worker)->flush_wait = PROXY_FLUSH_WAIT; (*worker)->smax = -1; - /* Increase the total worker count */ + (*worker)->our_hash = ap_proxy_hashfunc((*worker)->name, PROXY_HASHFUNC_PROXY); + (*worker)->apr_hash = ap_proxy_hashfunc((*worker)->name, PROXY_HASHFUNC_APR); (*worker)->cp = NULL; (*worker)->mutex = NULL; return NULL; } +PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker, + apr_pool_t *p, + proxy_server_conf *conf, + const char *url) +{ + return ap_proxy_add_worker_wid(worker, p, conf, url, -1); +} + PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker_wid(apr_pool_t *p, int id) { @@ -1504,6 +1516,11 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker_wid(apr_pool_t *p, int id) return worker; } +PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p) +{ + return ap_proxy_create_worker_wid(p, -1); +} + PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer_wid(apr_pool_t *pool, proxy_balancer *balancer, proxy_worker *worker, int id) @@ -1519,22 +1536,10 @@ ap_proxy_add_worker_to_balancer_wid(apr_pool_t *pool, proxy_balancer *balancer, } else { (*runtime)->id = id; } + balancer->updated = apr_time_now(); } -PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker, - apr_pool_t *p, - proxy_server_conf *conf, - const char *url) -{ - return ap_proxy_add_worker_wid(worker, p, conf, url, -1); -} - -PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p) -{ - return ap_proxy_create_worker_wid(p, -1); -} - PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool, proxy_balancer *balancer, proxy_worker *worker) @@ -1896,6 +1901,8 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, } worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED); + worker->s->apr_hash = worker->apr_hash; + worker->s->our_hash = worker->our_hash; } @@ -2744,3 +2751,27 @@ ap_proxy_buckets_lifetime_transform(request_rec *r, apr_bucket_brigade *from, } return rv; } + +/* + * Provide a string hashing function for the proxy. + * We offer 2 method: one is the APR model but we + * also provide our own, based on SDBM. The reason + * is in case we want to use both to ensure no + * collisions + */ +PROXY_DECLARE(unsigned int) +ap_proxy_hashfunc(const char *str, proxy_hash_t method) +{ + if (method == PROXY_HASHFUNC_APR) { + apr_ssize_t slen = strlen(str); + return apr_hashfunc_default(str, &slen); + } else { + /* SDBM model */ + unsigned int hash; + for(hash = 0; *str; str++) { + hash = (*str) + (hash << 6) + (hash << 16) - hash; + } + return hash; + } + +}