Author: jfrederic.clere(a)jboss.com
Date: 2009-01-14 09:23:20 -0500 (Wed, 14 Jan 2009)
New Revision: 2166
Modified:
trunk/mod_cluster/native/mod_manager/mod_manager.c
trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c
Log:
Add the missing part for the sessionid handling.
Modified: trunk/mod_cluster/native/mod_manager/mod_manager.c
===================================================================
--- trunk/mod_cluster/native/mod_manager/mod_manager.c 2009-01-13 21:24:04 UTC (rev 2165)
+++ trunk/mod_cluster/native/mod_manager/mod_manager.c 2009-01-14 14:23:20 UTC (rev 2166)
@@ -53,7 +53,7 @@
#define DEFMAXCONTEXT 100
#define DEFMAXNODE 10
#define DEFMAXHOST 20
-#define DEFMAXSESSIONID 2048
+#define DEFMAXSESSIONID 512
#define MAXMESSSIZE 1024
/* Error messages */
@@ -1271,6 +1271,8 @@
if (r->method_number != M_GET)
return DECLINED;
process_info(r, NULL, NULL);
+ /* refresh it every 10 seconds */
+ apr_table_set(r->headers_out, "Refresh", "10");
return OK;
}
@@ -1538,6 +1540,7 @@
ap_register_provider(p, "manager" , "shared", "1",
&host_storage);
ap_register_provider(p, "manager" , "shared", "2",
&context_storage);
ap_register_provider(p, "manager" , "shared", "3",
&balancer_storage);
+ ap_register_provider(p, "manager" , "shared", "4",
&sessionid_storage);
}
/*
Modified: trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c
===================================================================
--- trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c 2009-01-13 21:24:04 UTC
(rev 2165)
+++ trunk/mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c 2009-01-14 14:23:20 UTC
(rev 2166)
@@ -46,6 +46,7 @@
#include "host.h"
#include "context.h"
#include "balancer.h"
+#include "sessionid.h"
struct proxy_cluster_helper {
int count_active; /* currently active request using the worker */
@@ -62,12 +63,14 @@
static struct host_storage_method *host_storage = NULL;
static struct context_storage_method *context_storage = NULL;
static struct balancer_storage_method *balancer_storage = NULL;
+static struct sessionid_storage_method *sessionid_storage = NULL;
static apr_thread_mutex_t *lock = NULL;
#define WAITFORREMOVE 10 /* seconds */
-#define TIMEINTERVAL apr_time_from_sec(1) /* recalcul the lbstatus based on number of
request in the time interval */
+#define TIMEINTERVAL apr_time_from_sec(1) /* recalcul the lbstatus based on number of
request in the time interval */
+#define TIMESESSIONID apr_time_from_sec(300) /* after 5 minutes the sessionid have
probably timeout */
/* reslist constructor */
/* XXX: Should use the proxy_util one. */
@@ -627,6 +630,32 @@
}
}
+/*
+ * remove the sessionids that have timeout
+ */
+static void remove_timeout_sessionid(proxy_server_conf *conf, apr_pool_t *pool,
server_rec *server)
+{
+ int *id, size, i;
+ apr_time_t now;
+ int notok = 0;
+
+ now = apr_time_now();
+
+ /* read the ident of the sessionid */
+ id = apr_pcalloc(pool, sizeof(int) *
sessionid_storage->get_max_size_sessionid());
+ size = sessionid_storage->get_ids_used_sessionid(id);
+
+ /* update lbstatus if needed */
+ for (i=0; i<size; i++) {
+ sessionidinfo_t *ou;
+ sessionid_storage->read_sessionid(id[i], &ou);
+ if (ou->updatetime < (now - TIMESESSIONID)) {
+ /* Remove it */
+ sessionid_storage->remove_sessionid(ou);
+ }
+ }
+}
+
/* Retrieve the parameter with the given name
* Something like 'JSESSIONID=12345...N'
* XXX: Should use the mod_proxy_balancer ones.
@@ -695,7 +724,7 @@
* @param uri part of the URL to for the session parameter.
* @param sticky_used the string that was used to find the route
*/
-static char *get_route(request_rec *r, const char *stickyval, char *uri, char
**sticky_used)
+static char *cluster_get_sessionid(request_rec *r, const char *stickyval, char *uri, char
**sticky_used)
{
char *sticky, *sticky_path;
char *path;
@@ -727,7 +756,7 @@
static int hassession_byname(request_rec *r, char *balancer_name, proxy_server_conf
*conf, proxy_balancer *balance)
{
proxy_balancer *balancer = balance;
- char *route;
+ char *sessionid;
char *uri = r->filename + 6;
char *sticky_used;
int i;
@@ -749,10 +778,10 @@
if (balancer->sticky == NULL)
return 0;
- route = get_route(r, balancer->sticky, uri, &sticky_used);
- if (route) {
+ sessionid = cluster_get_sessionid(r, balancer->sticky, uri, &sticky_used);
+ if (sessionid) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
- "mod_proxy_cluster: found route %s", route);
+ "mod_proxy_cluster: found sessionid %s", sessionid);
return 1;
}
return 0;
@@ -1311,6 +1340,8 @@
remove_removed_node(pool, s);
/* Calculate the lbstatus for each node */
update_workers_lbstatus(conf, pool, s);
+ /* Free sessionid slots */
+ remove_timeout_sessionid(conf, pool, s);
apr_pool_destroy(pool);
}
apr_thread_exit(thd, 0);
@@ -1376,6 +1407,12 @@
"proxy_cluster_post_config: Can't find mod_manager for
balancers");
return !OK;
}
+ sessionid_storage = ap_lookup_provider("manager" , "shared",
"4");
+ if (sessionid_storage == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
+ "proxy_cluster_post_config: Can't find mod_manager for
sessionids");
+ return !OK;
+ }
return OK;
}
@@ -1387,6 +1424,7 @@
{
proxy_balancer *balancer;
char *route = NULL;
+ char *sessionid = NULL;
char *sticky_used;
int i;
void *sconf = r->server->module_config;
@@ -1399,12 +1437,12 @@
if (balancer->sticky == NULL)
continue;
- route = get_route(r, balancer->sticky, r->uri, &sticky_used);
- if (route) {
+ sessionid = cluster_get_sessionid(r, balancer->sticky, r->uri,
&sticky_used);
+ if (sessionid) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"cluster: Found value %s for "
- "stickysession %s", route, balancer->sticky);
- if ((route = strchr(route, '.')) != NULL )
+ "stickysession %s", sessionid, balancer->sticky);
+ if ((route = strchr(sessionid, '.')) != NULL )
route++;
if (route && *route) {
nodeinfo_t *ou;
@@ -1415,8 +1453,12 @@
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"cluster: Found balancer %s for %s",
ou->mess.balancer, route);
/* here we have the route and domain for find_session_route ...
*/
- apr_table_setn(r->notes, "CLUSTER_ROUTE", route);
- apr_table_setn(r->notes, "CLUSTER_STICKY_USED",
sticky_used);
+ apr_table_setn(r->notes, "session-sticky",
sticky_used);
+ apr_table_setn(r->notes, "session-id", sessionid);
+ apr_table_setn(r->notes, "session-route", route);
+
+ apr_table_setn(r->subprocess_env,
"BALANCER_SESSION_ROUTE", route);
+ apr_table_setn(r->subprocess_env,
"BALANCER_SESSION_STICKY", sticky_used);
if (ou->mess.Domain[0] != '\0') {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"cluster: Found domain %s for %s",
ou->mess.Domain, route);
@@ -1562,14 +1604,14 @@
return NULL;
/* We already should have the route in the notes for the trans() */
- *route = apr_table_get(r->notes, "CLUSTER_ROUTE");
+ *route = apr_table_get(r->notes, "session-route");
if (*route && (**route)) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"cluster: Using route %s", *route);
} else
return NULL;
- *sticky_used = apr_table_get(r->notes, "CLUSTER_STICKY_USED");
+ *sticky_used = apr_table_get(r->notes, "session-sticky");
if (domain)
*domain = apr_table_get(r->notes, "CLUSTER_DOMAIN");
@@ -1769,12 +1811,12 @@
*/
if (*balancer) {
/* Adjust the helper->count corresponding to the previous try */
- const char *domain = apr_table_get(r->subprocess_env,
"BALANCER_WORKER_NAME");
+ const char *worker_name = apr_table_get(r->subprocess_env,
"BALANCER_WORKER_NAME");
if (domain && *domain) {
int i;
runtime = (proxy_worker *)(*balancer)->workers->elts;
for (i = 0; i < (*balancer)->workers->nelts; i++, runtime++) {
- if (runtime->name && strcmp(domain, runtime->name) == 0) {
+ if (runtime->name && strcmp(worker_name, runtime->name) ==
0) {
proxy_cluster_helper *helper;
helper = (proxy_cluster_helper *) (runtime)->opaque;
if (helper->count_active>0)
@@ -1876,8 +1918,8 @@
/*
* Failover to another domain. Remove sessionid information.
*/
- const char *domain = apr_table_get(r->notes,
"session-domain-ok");
- if (!domain) {
+ const char *domain_ok = apr_table_get(r->notes,
"session-domain-ok");
+ if (!domain_ok) {
remove_session_route(r, sticky);
}
}
@@ -1886,13 +1928,15 @@
(*worker)->s->busy++;
+ /*
+ * get_route_balancer already fills all of the notes and some subprocess_env
+ * but not all.
+ * Note that BALANCER_WORKER_NAME would have changed in case of failover.
+ */
/* Add balancer/worker info to env. */
- apr_table_setn(r->subprocess_env,
- "BALANCER_NAME", (*balancer)->name);
- apr_table_setn(r->subprocess_env,
- "BALANCER_WORKER_NAME", (*worker)->name);
- apr_table_setn(r->subprocess_env,
- "BALANCER_WORKER_ROUTE", (*worker)->s->route);
+ apr_table_setn(r->subprocess_env, "BALANCER_NAME",
(*balancer)->name);
+ apr_table_setn(r->subprocess_env, "BALANCER_WORKER_NAME",
(*worker)->name);
+ apr_table_setn(r->subprocess_env, "BALANCER_WORKER_ROUTE",
(*worker)->s->route);
/* Rewrite the url from 'balancer://url'
* to the 'worker_scheme://worker_hostname[:worker_port]/url'
@@ -1900,17 +1944,7 @@
* real hostname of the elected worker.
*/
access_status = rewrite_url(r, *worker, url);
- /* Add the session route to request notes if present */
- if (route) {
- apr_table_setn(r->notes, "session-sticky", sticky);
- apr_table_setn(r->notes, "session-route", route);
- /* Add session info to env. */
- apr_table_setn(r->subprocess_env,
- "BALANCER_SESSION_STICKY", sticky);
- apr_table_setn(r->subprocess_env,
- "BALANCER_SESSION_ROUTE", route);
- }
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: CLUSTER (%s) worker (%s) rewritten to %s",
(*balancer)->name, (*worker)->name, *url);
@@ -1926,6 +1960,8 @@
apr_status_t rv;
proxy_cluster_helper *helper;
+ const char *sessionid;
+ const char *route;
if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
@@ -1948,7 +1984,15 @@
if (worker && worker->s->busy)
worker->s->busy--;
- /* XXX: Add information about sessions corresponding to a node */
+ /* Add information about sessions corresponding to a node */
+ sessionid = apr_table_get(r->notes, "session-id");
+ route = apr_table_get(r->notes, "session-route");
+ if (sessionid && route) {
+ sessionidinfo_t ou;
+ strncpy(ou.sessionid, sessionid, SESSIONIDSZ);
+ strncpy(ou.JVMRoute, route, JVMROUTESZ);
+ sessionid_storage->insert_update_sessionid(&ou);
+ }
return OK;
}