hlship 2004/08/12 14:27:35
Modified: framework/src/test/org/apache/hivemind/servlet
TestHiveMindFilter.java
framework/src/java/org/apache/hivemind/servlet
HiveMindFilter.java
Log:
Add support into HiveMindFilter to allow the current Registry to be shutdown
and replaced with a fresh one.
Revision Changes Path
1.2 +93 -6
jakarta-hivemind/framework/src/test/org/apache/hivemind/servlet/TestHiveMindFilter.java
Index: TestHiveMindFilter.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/test/org/apache/hivemind/servlet/TestHiveMindFilter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestHiveMindFilter.java 11 Aug 2004 22:13:26 -0000 1.1
+++ TestHiveMindFilter.java 12 Aug 2004 21:27:35 -0000 1.2
@@ -14,15 +14,22 @@
package org.apache.hivemind.servlet;
+import java.io.IOException;
+
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.HiveMind;
import org.apache.hivemind.Registry;
+import org.apache.hivemind.ShutdownCoordinator;
+import org.apache.hivemind.events.RegistryShutdownListener;
import org.apache.hivemind.service.ThreadCleanupListener;
import org.apache.hivemind.service.ThreadEventNotifier;
import org.apache.hivemind.test.HiveMindTestCase;
@@ -35,7 +42,7 @@
*/
public class TestHiveMindFilter extends HiveMindTestCase
{
- private static class Listener implements ThreadCleanupListener
+ private static class ThreadListenerFixture implements
ThreadCleanupListener
{
private boolean _cleanup;
@@ -51,6 +58,22 @@
}
+ private static class ShutdownListenerFixture implements
RegistryShutdownListener
+ {
+ private boolean _didShutdown;
+
+ public void registryDidShutdown()
+ {
+ _didShutdown = true;
+ }
+
+ public boolean getDidShutdown()
+ {
+ return _didShutdown;
+ }
+
+ }
+
private static class HiveMindFilterFixture extends HiveMindFilter
{
@@ -61,6 +84,15 @@
}
+ private static class RebuildRegistryChainFixture implements FilterChain
+ {
+ public void doFilter(ServletRequest request, ServletResponse
response)
+ throws IOException, ServletException
+ {
+ HiveMindFilter.rebuildRegistry((HttpServletRequest) request);
+ }
+ }
+
public void testBasic() throws Exception
{
FilterConfig filterConfig = (FilterConfig)
newMock(FilterConfig.class);
@@ -82,7 +114,7 @@
HiveMind.THREAD_EVENT_NOTIFIER_SERVICE,
ThreadEventNotifier.class);
- Listener l = new Listener();
+ ThreadListenerFixture l = new ThreadListenerFixture();
t.addThreadCleanupListener(l);
@@ -93,11 +125,14 @@
request.setAttribute(HiveMindFilter.REQUEST_KEY, r);
+ chain.doFilter(request, response);
+
+ request.getAttribute(HiveMindFilter.REBUILD_REQUEST_KEY);
+ requestControl.setReturnValue(null);
+
request.getAttribute(HiveMindFilter.REQUEST_KEY);
requestControl.setReturnValue(r);
- chain.doFilter(request, response);
-
replayControls();
f.doFilter(request, response, chain);
@@ -121,6 +156,50 @@
verifyControls();
}
+ public void testShutdown() throws Exception
+ {
+ FilterConfig filterConfig = (FilterConfig)
newMock(FilterConfig.class);
+
+ replayControls();
+
+ HiveMindFilter f = new HiveMindFilter();
+
+ f.init(filterConfig);
+
+ verifyControls();
+
+ Registry r = f.getRegistry();
+
+ assertNotNull(r);
+
+ ShutdownCoordinator coordinator =
+ (ShutdownCoordinator) r.getService(ShutdownCoordinator.class);
+
+ ShutdownListenerFixture l = new ShutdownListenerFixture();
+
+ coordinator.addRegistryShutdownListener(l);
+
+ MockControl requestControl = newControl(HttpServletRequest.class);
+ HttpServletRequest request = (HttpServletRequest)
requestControl.getMock();
+ HttpServletResponse response = (HttpServletResponse)
newMock(HttpServletResponse.class);
+ FilterChain chain = new RebuildRegistryChainFixture();
+
+ request.setAttribute(HiveMindFilter.REQUEST_KEY, r);
+
+ request.setAttribute(HiveMindFilter.REBUILD_REQUEST_KEY,
Boolean.TRUE);
+
+ request.getAttribute(HiveMindFilter.REBUILD_REQUEST_KEY);
+ requestControl.setReturnValue(Boolean.TRUE);
+
+ replayControls();
+
+ f.doFilter(request, response, chain);
+
+ verifyControls();
+
+ assertEquals(true, l.getDidShutdown());
+ }
+
public void testExceptionInInit() throws Exception
{
Filter f = new HiveMindFilterFixture();
@@ -131,7 +210,8 @@
assertLoggedMessage("Forced failure");
- HttpServletRequest request = (HttpServletRequest)
newMock(HttpServletRequest.class);
+ MockControl requestControl = newControl(HttpServletRequest.class);
+ HttpServletRequest request = (HttpServletRequest)
requestControl.getMock();
HttpServletResponse response = (HttpServletResponse)
newMock(HttpServletResponse.class);
FilterChain chain = (FilterChain) newMock(FilterChain.class);
@@ -139,6 +219,9 @@
chain.doFilter(request, response);
+ request.getAttribute(HiveMindFilter.REBUILD_REQUEST_KEY);
+ requestControl.setReturnValue(null);
+
replayControls();
f.doFilter(request, response, chain);
@@ -161,13 +244,17 @@
interceptLogging(HiveMindFilter.class.getName());
- HttpServletRequest request = (HttpServletRequest)
newMock(HttpServletRequest.class);
+ MockControl requestControl = newControl(HttpServletRequest.class);
+ HttpServletRequest request = (HttpServletRequest)
requestControl.getMock();
HttpServletResponse response = (HttpServletResponse)
newMock(HttpServletResponse.class);
FilterChain chain = (FilterChain) newMock(FilterChain.class);
request.setAttribute(HiveMindFilter.REQUEST_KEY, null);
chain.doFilter(request, response);
+
+ request.getAttribute(HiveMindFilter.REBUILD_REQUEST_KEY);
+ requestControl.setReturnValue(null);
replayControls();
1.10 +54 -2
jakarta-hivemind/framework/src/java/org/apache/hivemind/servlet/HiveMindFilter.java
Index: HiveMindFilter.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/servlet/HiveMindFilter.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- HiveMindFilter.java 11 Aug 2004 22:13:26 -0000 1.9
+++ HiveMindFilter.java 12 Aug 2004 21:27:35 -0000 1.10
@@ -51,6 +51,9 @@
static final String REQUEST_KEY = "org.apache.hivemind.RequestRegistry";
+ static final String REBUILD_REQUEST_KEY =
"org.apache.hivemind.RebuildRegistry";
+
+ private FilterConfig _filterConfig;
private Registry _registry;
/**
@@ -67,13 +70,21 @@
*/
public void init(FilterConfig config) throws ServletException
{
+ _filterConfig = config;
+
+ initializeRegistry();
+
+ }
+
+ private void initializeRegistry()
+ {
long startTime = System.currentTimeMillis();
LOG.info(ServletMessages.filterInit());
try
{
- _registry = constructRegistry(config);
+ _registry = constructRegistry(_filterConfig);
LOG.info(
ServletMessages.constructedRegistry(
@@ -127,8 +138,38 @@
finally
{
cleanupThread();
+
+ checkRegistryRebuild(request);
}
+ }
+
+ private synchronized void checkRegistryRebuild(ServletRequest request)
+ {
+ if (request.getAttribute(REBUILD_REQUEST_KEY) == null)
+ return;
+ // This is so not threadsafe, but you don't do this very often.
+ // This method is synchronized, but other threads may be actively
using
+ // the Registry we're shutting down.
+
+ // What we really need is some good concurrence support to track the
number
+ // of threads that may be using the old registry, set a write lock,
and wait
+ // for that number to drop to one (this thread). Instead, we'll
just swap in the
+ // new Registry and hope for the best.
+
+ Registry oldRegistry = _registry;
+
+ // Replace the old Registry with a new one. All other threads, but
this
+ // one, will begin using the new Registry. Hopefully, we didn't get
+ // rebuild requests on multiple threads.
+
+ initializeRegistry();
+
+ // Shutdown the old Registry. Perhaps we should sleep for a moment,
first,
+ // to help ensure that other threads have "cleared out". If not,
we'll see some
+ // instability at the instant we shutdown (i.e., all the proxies
will get disabled).
+
+ oldRegistry.shutdown();
}
/**
@@ -153,15 +194,26 @@
{
if (_registry != null)
_registry.shutdown();
+
+ _filterConfig = null;
}
/**
* Returns the [EMAIL PROTECTED] Registry} that was stored as a request
attribute
- * in [EMAIL PROTECTED] #doFilter(ServletRequest, ServletResponse,
FilterChain)}.
+ * inside method [EMAIL PROTECTED] #doFilter(ServletRequest,
ServletResponse, FilterChain)}.
*/
public static Registry getRegistry(HttpServletRequest request)
{
return (Registry) request.getAttribute(REQUEST_KEY);
+ }
+
+ /**
+ * Sets a flag in the request that will cause the current Registry to
be shutdown
+ * and replaced with a new Registry (at the end of the current request).
+ */
+ public static void rebuildRegistry(HttpServletRequest request)
+ {
+ request.setAttribute(REBUILD_REQUEST_KEY, Boolean.TRUE);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]