* 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" */
/* 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 )
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 */
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. */
};
/*
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 {
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"
#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;
/* 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);
#include "ap_mpm.h"
#include "scoreboard.h"
#include "apr_version.h"
+#include "apr_hash.h"
#if APR_HAVE_UNISTD_H
#include <unistd.h> /* for getpid() */
(*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),
(*worker)->port = uri.port;
if (id < 0) {
(*worker)->id = proxy_lb_workers;
+ /* Increase the total worker count */
proxy_lb_workers++;
} else {
(*worker)->id = id;
(*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)
{
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)
} 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)
}
worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED);
+ worker->s->apr_hash = worker->apr_hash;
+ worker->s->our_hash = worker->our_hash;
}
}
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;
+ }
+
+}