I needed to be able to add URIs handled by JK2 to the
workers2.properties config file and have those new endpoints work
dynamically, without restarting Apache 2.  The existing code to reload
the config file when hitting the status worker page accomplished 99% of
the work.  The included patch file does the extra 1% needed to handle
new URIs.

Highlights
1) Adds a refresh method to the UriMap data structure
2) Adds a checkVersion method to workerEnv data structure to compare
config version against shared memory segment and reload config if
necessary.  This is similar to what the lb worker does, and was
necessary to support multi-process operation.
3) checkVersion call was added to the jk2_translate hook.  This is
because the data structures must be reloaded before the translation
phase of mod_jk2.  Once again, this was necessary for multi-process
operation.

The patch can be applied against the 2.0.4 release of the JK2 source
tarball.  It has been tested with Apache 2.0.49 with Tomcat 4.1.29 on
RHEL 3 and Fedora.  It has been tested multi-threaded, multi-process
using the worker MPM.

We at Epok are contributing this patch back to the Jakarta community
with no claims on copyright and no warranty.  You can do whatever you
want to with this code without contacting me or Epok.  It would be nice
to have this functionality incorporated into JK2 in some future
release.  Clearly, this functionality would be implemented differently
if done by the Tomcat developer team.  Hopefully, this patch can serve
as a reference.

Keep up the good work,

Chetan
diff -urNp jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/common/jk_uriMap.c jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/common/jk_uriMap.c
--- jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/common/jk_uriMap.c	2004-03-24 08:33:15.000000000 -0500
+++ jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/common/jk_uriMap.c	2004-04-13 15:27:00.000000000 -0400
@@ -806,21 +806,12 @@ static int jk2_uriMap_createGlobals(jk_e
     return JK_OK;
 }
 
-static int jk2_uriMap_init(jk_env_t *env, jk_uriMap_t *uriMap)
+static int jk2_uriMap_refresh(jk_env_t *env, jk_uriMap_t *uriMap)
 {
     int rc = JK_OK;
-    jk_workerEnv_t *workerEnv = uriMap->workerEnv;
-    jk_bean_t *mbean = env->getBean2(env, "uri", "*");
 
-    /* create the default server */
-    if (mbean == NULL) {
-        mbean = env->createBean2(env, workerEnv->pool, "uri", "*");
-        if (mbean == NULL || mbean->object == NULL) {
-            env->l->jkLog(env, env->l, JK_LOG_ERROR,
-                          "uriMap.factory() Fail to create default host\n");
-            return JK_ERR;
-        }
-    }
+    uriMap->vhosts->clear(env, uriMap->vhosts);
+    uriMap->vhcache->clear(env, uriMap->vhcache);
 
     /* Create virtual hosts and initialize them */
     jk2_uriMap_createHosts(env, uriMap);
@@ -838,6 +829,24 @@ static int jk2_uriMap_init(jk_env_t *env
     return rc;
 }
 
+static int jk2_uriMap_init(jk_env_t *env, jk_uriMap_t *uriMap)
+{
+    jk_workerEnv_t *workerEnv = uriMap->workerEnv;
+    jk_bean_t *mbean = env->getBean2(env, "uri", "*");
+
+    /* create the default server */
+    if (mbean == NULL) {
+        mbean = env->createBean2(env, workerEnv->pool, "uri", "*");
+        if (mbean == NULL || mbean->object == NULL) {
+            env->l->jkLog(env, env->l, JK_LOG_ERROR,
+                          "uriMap.factory() Fail to create default host\n");
+            return JK_ERR;
+        }
+    }
+
+    return uriMap->refresh(env, uriMap);
+}
+
 static void jk2_uriMap_destroy(jk_env_t *env, jk_uriMap_t *uriMap)
 {
 
@@ -1109,6 +1118,7 @@ int JK_METHOD jk2_uriMap_factory(jk_env_
 
     uriMap->init = jk2_uriMap_init;
     uriMap->destroy = jk2_uriMap_destroy;
+    uriMap->refresh = jk2_uriMap_refresh;
     uriMap->addUriEnv = jk2_uriMap_addUriEnv;
     uriMap->checkUri = jk2_uriMap_checkUri;
     uriMap->mapUri = jk2_uriMap_mapUri;
diff -urNp jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/common/jk_workerEnv.c jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/common/jk_workerEnv.c
--- jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/common/jk_workerEnv.c	2004-03-24 08:33:15.000000000 -0500
+++ jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/common/jk_workerEnv.c	2004-04-13 15:31:17.000000000 -0400
@@ -675,6 +675,40 @@ static jk_worker_t *jk2_workerEnv_create
     return w;
 }
 
+static int jk2_workerEnv_checkVersion(jk_env_t *env, jk_workerEnv_t *wEnv)
+{
+    int err = JK_OK;
+
+    if (wEnv->shm != NULL && wEnv->shm->head != NULL) {
+        /* We have shm, let's check for updates. This is just checking one
+           memory location, no lock involved. It is possible we'll read it
+           while somebody else is changing - but that's ok, we just check for
+           equality.
+         */
+        /* We should check this periodically
+         */
+        if (wEnv->config->ver != wEnv->shm->head->lbVer) {
+            if (wEnv->cs != NULL)
+                wEnv->cs->lock(env, wEnv->cs);
+
+            /* check condition again to avoid duplicate work */
+            env->l->jkLog(env, env->l, JK_LOG_DEBUG, "workerEnv.checkVersion() checking version inside mutex\n");
+            if (wEnv->config->ver != wEnv->shm->head->lbVer) {
+                wEnv->config->update(env, wEnv->config, NULL);
+                wEnv->uriMap->refresh(env, wEnv->uriMap);
+                wEnv->config->ver = wEnv->shm->head->lbVer;
+
+                env->l->jkLog(env, env->l, JK_LOG_INFO, "workerEnv.checkVersion() updated config\n");
+            }
+
+            if (wEnv->cs != NULL)
+                wEnv->cs->unLock(env, wEnv->cs);
+        }
+    }
+
+    return JK_OK;
+}
+
 
 int JK_METHOD jk2_workerEnv_factory(jk_env_t *env, jk_pool_t *pool,
                                     jk_bean_t *result,
@@ -762,6 +796,7 @@ int JK_METHOD jk2_workerEnv_factory(jk_e
     wEnv->addChannel = &jk2_workerEnv_addChannel;
     wEnv->addEndpoint = &jk2_workerEnv_addEndpoint;
     wEnv->initChannel = &jk2_workerEnv_initChannel;
+    wEnv->checkVersion = &jk2_workerEnv_checkVersion;
     wEnv->registerHandler = &jk2_workerEnv_registerHandler;
     wEnv->processCallbacks = &jk2_workerEnv_processCallbacks;
     wEnv->dispatch = &jk2_workerEnv_dispatch;
diff -urNp jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/common/jk_worker_status.c jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/common/jk_worker_status.c
--- jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/common/jk_worker_status.c	2004-03-24 08:33:15.000000000 -0500
+++ jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/common/jk_worker_status.c	2004-04-13 14:47:38.000000000 -0400
@@ -1010,10 +1010,16 @@ static int JK_METHOD jk2_worker_status_s
     /** Updating the config is the first thing we do.
         All other operations will happen on the update config.
       */
+    if (w->workerEnv->cs != NULL) {
+        w->workerEnv->cs->lock(env, w->workerEnv->cs);
+    }
+
     w->workerEnv->config->update(env, w->workerEnv->config, &didUpdate);
     env->l->jkLog(env, env->l, JK_LOG_DEBUG,
                   "status.update check %d\n", didUpdate);
     if (didUpdate) {
+        w->workerEnv->uriMap->refresh(env, w->workerEnv->uriMap);
+
         jk_shm_t *shm = w->workerEnv->shm;
 
         /* Update the scoreboard's version - all other
@@ -1029,6 +1035,9 @@ static int JK_METHOD jk2_worker_status_s
         }
     }
 
+    if (w->workerEnv->cs != NULL) {
+        w->workerEnv->cs->unLock(env, w->workerEnv->cs);
+    }
 
     /* Increment the scoreboard version counter, reload */
     if (strncmp(s->query_string, "rld=", 4) == 0) {
diff -urNp jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/include/jk_uriMap.h jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/include/jk_uriMap.h
--- jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/include/jk_uriMap.h	2004-03-24 08:33:15.000000000 -0500
+++ jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/include/jk_uriMap.h	2004-04-13 14:48:40.000000000 -0400
@@ -85,6 +85,10 @@ extern "C"
 
         void (*destroy) (struct jk_env * env, jk_uriMap_t *_this);
 
+    /** Refresh the map. Repopulates internal data structures
+    */
+        int (*refresh) (struct jk_env * env, jk_uriMap_t *_this);
+
         int (*addUriEnv) (struct jk_env * env,
                           struct jk_uriMap * uriMap,
                           struct jk_uriEnv * uriEnv);
diff -urNp jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/include/jk_workerEnv.h jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/include/jk_workerEnv.h
--- jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/include/jk_workerEnv.h	2004-03-24 08:33:15.000000000 -0500
+++ jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/include/jk_workerEnv.h	2004-04-13 13:44:52.000000000 -0400
@@ -254,6 +254,11 @@ extern "C"
                             struct jk_workerEnv * wEnv,
                             struct jk_channel * ch);
 
+    /** Check for any configuration changes and update if necessary
+    */
+        int (*checkVersion) (struct jk_env * env,
+                            struct jk_workerEnv * wEnv);
+
     /** Call the handler associated with the message type.
      */
         int (*dispatch) (struct jk_env * env, struct jk_workerEnv * _this,
diff -urNp jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/server/apache2/mod_jk2.c jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/server/apache2/mod_jk2.c
--- jakarta-tomcat-connectors-jk2-2.0.4-src/jk/native2/server/apache2/mod_jk2.c	2004-03-24 08:33:15.000000000 -0500
+++ jakarta-tomcat-connectors-jk2-2.0.4-css/jk/native2/server/apache2/mod_jk2.c	2004-04-13 14:50:35.000000000 -0400
@@ -774,6 +774,12 @@ static int jk2_translate(request_rec * r
     if (r->proxyreq || workerEnv == NULL) {
         return DECLINED;
     }
+    
+    /* Get an env instance */
+    env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
+    
+    /* check for any configuration updates */
+    workerEnv->checkVersion(env, workerEnv);
 
     /* For the JkUriSet */
     uriEnv = ap_get_module_config(r->per_dir_config, &jk2_module);
@@ -783,8 +789,6 @@ static int jk2_translate(request_rec * r
      * but that's too complex for now.
      */
     if (uriEnv != NULL && uriEnv->workerName != NULL) {
-        /* get_env() */
-        env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
 
         if (uriEnv->mbean->debug > 0)
             env->l->jkLog(env, env->l, JK_LOG_DEBUG,

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to