raphael 2002/11/03 07:09:47
Modified: src/java/org/apache/jetspeed/services/registry
CastorRegistryService.java FileRegistry.java
RegistryFragment.java RegistryWatcher.java
Log:
Fix Registry performance issue by changing the way fragments are persisted
Revision Changes Path
1.23 +132 -73
jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java
Index: CastorRegistryService.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- CastorRegistryService.java 30 Oct 2002 15:52:39 -0000 1.22
+++ CastorRegistryService.java 3 Nov 2002 15:09:47 -0000 1.23
@@ -90,6 +90,7 @@
import java.io.Reader;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Map;
import java.util.Iterator;
import java.util.Vector;
import javax.servlet.ServletConfig;
@@ -115,6 +116,8 @@
* refreshRate seconds if the config has changed and if true will refresh
* all the registries. A value of 0 or negative will disable the
* automatic refresh operation. Default: 300 (5 minutes)</dd>
+ * <dt>verbose</dt><dd>Optional. Control the amount of debug output. The bigger
+ * the more output, you've been warned ! Default: 0</dd>
* </dl>
* </p>
*
@@ -127,10 +130,14 @@
implements RegistryService, FileRegistry
{
+ public static final int DEFAULT_VERBOSE = 0;
public static final int DEFAULT_REFRESH = 300;
public static final String DEFAULT_EXTENSION = ".xreg";
public static final String DEFAULT_MAPPING =
"${webappRoot}/WEB-INF/conf/mapping.xml";
+ /** controls amount of debug output, the bigger the more output will be
generated */
+ public int verbose = DEFAULT_VERBOSE;
+
/** regsitry type keyed list of entries */
private Hashtable registries = new Hashtable();
@@ -188,16 +195,16 @@
*/
public RegistryEntry createEntry(String regName)
{
- RegistryEntry entry = null;
+ RegistryEntry entry = null;
Registry registry = (Registry) registries.get(regName);
if (registry != null)
{
- entry = registry.createEntry();
+ entry = registry.createEntry();
}
- return entry;
- }
+ return entry;
+ }
/**
* Returns a RegistryEntry from the named Registry.
@@ -217,14 +224,14 @@
}
catch (RegistryException e)
{
- if (Log.getLogger().isInfoEnabled())
- {
- Log.info("Failed to retrieve " + entryName + " from " + regName);
- }
+ if (Log.getLogger().isInfoEnabled())
+ {
+ Log.info("RegistryService: Failed to retrieve " + entryName + "
from " + regName);
+ }
}
catch (NullPointerException e)
{
- Log.error(regName + " registry is not known ");
+ Log.error("RegistryService: "+ regName + " registry is not known ");
Log.error(e);
}
@@ -293,10 +300,10 @@
}
entryIndex.put(entry.getName(), fragmentName);
+ // mark this fragment so that it's persisted next time
+ // the registry watcher is running
+ fragment.setDirty(true);
}
-
- //As it has changed...
- saveFragment(fragmentName);
}
}
@@ -329,15 +336,15 @@
{
fragment.removeEntry(regName, entryName);
entryIndex.remove(entryName);
+
+ // mark this fragment so that it's persisted next time
+ // the registry watcher is running
+ fragment.setDirty(true);
}
}
// the entry is physically removed, remove the dangling reference
registry.removeLocalEntry(entryName);
-
- //As the fragment has changed...
- saveFragment(fragmentName);
-
}
}
@@ -345,7 +352,7 @@
* This is the early initialization method called by the
* Turbine <code>Service</code> framework
*/
- public void init(ServletConfig conf) throws InitializationException
+ public synchronized void init(ServletConfig conf) throws InitializationException
{
//Ensure that the servlet service is initialized
@@ -364,6 +371,7 @@
mapFile = serviceConf.getString("mapping", DEFAULT_MAPPING);
extension = serviceConf.getString("extension", DEFAULT_EXTENSION);
refreshRate = serviceConf.getInt("refreshRate", DEFAULT_REFRESH);
+ verbose = serviceConf.getInt("verbose", DEFAULT_VERBOSE);
mapFile = TurbineServlet.getRealPath(mapFile);
directory = TurbineServlet.getRealPath(directory);
@@ -394,7 +402,7 @@
}
catch (Exception e)
{
- Log.error("Registry init error", e);
+ Log.error("RegistryService: Registry init error", e);
throw new InitializationException("Unable to initialize
CastorRegistryService, invalid registries definition");
}
@@ -419,7 +427,7 @@
}
catch (Exception e)
{
- Log.error("Error in mapping creation", e);
+ Log.error("RegistryService: Error in mapping creation", e);
throw new InitializationException("Error in mapping", e);
}
}
@@ -463,24 +471,24 @@
if (registry == null)
{
- String registryClass = null;
+ String registryClass = null;
try
{
- registryClass =
-
"org.apache.jetspeed.om.registry.base.Base"
- + name
- + "Registry";
-
- registry =
(Registry)Class.forName(registryClass).newInstance();
- }
- catch (Exception e)
- {
- if (Log.getLogger().isWarnEnabled())
- {
- Log.warn("CastorRegistryService: Class
"
- + registryClass
- + " not found, reverting to
default Registry");
- }
+ registryClass =
+ "org.apache.jetspeed.om.registry.base.Base"
+ + name
+ + "Registry";
+
+ registry = (Registry)Class.forName(registryClass).newInstance();
+ }
+ catch (Exception e)
+ {
+ if (Log.getLogger().isWarnEnabled())
+ {
+ Log.warn("RegistryService: Class "
+ + registryClass
+ + " not found, reverting to default Registry");
+ }
registry = new BaseRegistry();
}
@@ -490,14 +498,11 @@
refresh(name);
}
- // Refresh the registry to make sure all <portlet-entry ... ref=""> are
loaded.
- Log.info("CasterRegistryService: Refreshing registry to insure entries are
loaded");
+ //refresh all registries
refresh();
- //Mark that we are done
- setInit(true);
-
- // Start the directory watcher thread
+ // Start the directory watcher thread and rely on its refresh process
+ // to completely load all registries
if (this.watcher != null)
{
this.watcher.start();
@@ -505,8 +510,8 @@
if (Log.getLogger().isDebugEnabled())
{
- Log.debug("Registry early init()....end!, this.getInit()= " +
getInit());
- }
+ Log.debug("RegistryService: early init()....end!, this.getInit()= " +
getInit());
+ }
}
@@ -515,8 +520,8 @@
{
if (Log.getLogger().isDebugEnabled())
{
- Log.debug("Late init for Registry called");
- }
+ Log.debug("RegistryService: Late init called");
+ }
while (!getInit())
{
@@ -524,7 +529,10 @@
try
{
Thread.sleep(500);
- Log.debug("Waiting for init of Registry...");
+ if ((verbose>2) && Log.getLogger().isDebugEnabled())
+ {
+ Log.debug("RegistryService: Waiting for init of Registry...");
+ }
}
catch (InterruptedException ie)
{
@@ -534,11 +542,10 @@
if (Log.getLogger().isDebugEnabled())
{
- Log.debug("We are done! (Registry)");
- }
+ Log.debug("RegistryService: We are done");
+ }
}
-
/**
* This is the shutdown method called by the
* Turbine <code>Service</code> framework
@@ -561,14 +568,25 @@
*/
public void refresh()
{
- Enumeration en = getNames();
- while (en.hasMoreElements())
+ synchronized (this)
{
- refresh((String) en.nextElement());
+ Enumeration en = getNames();
+ while (en.hasMoreElements())
+ {
+ refresh((String) en.nextElement());
+ }
}
}
/**
+ * @return a Map of all fragments keyed by file names
+ */
+ public Map getFragmentMap()
+ {
+ return (Map)fragments.clone();
+ }
+
+ /**
* Load and unmarshal a RegistryFragment from the file
* @param file the absolute file path storing this fragment
*/
@@ -584,13 +602,16 @@
Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
RegistryFragment fragment = (RegistryFragment)
unmarshaller.unmarshal((Node) d);
+ //mark this fragment as changed
+ fragment.setChanged(true);
+
// if we get here, we successfully loaded the new fragment
updateFragment(file, fragment);
}
catch (Throwable t)
{
- Log.error("Could not unmarshal: " + file, t);
+ Log.error("RegistryService: Could not unmarshal: " + file, t);
}
}
@@ -604,12 +625,17 @@
*/
public void createFragment(String name, Reader reader, boolean persistent)
{
- String file = new File(directory, name + extension).getAbsolutePath();
+ String file = null;
+
try
{
+ file = new File(directory, name + extension).getCanonicalPath();
+
Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
RegistryFragment fragment = (RegistryFragment)
unmarshaller.unmarshal(reader);
+ fragment.setChanged(true);
+
updateFragment(file, fragment);
if (persistent)
@@ -619,7 +645,7 @@
}
catch (Throwable t)
{
- Log.error("Could not create fragment: " + file, t);
+ Log.error("RegistryService: Could not create fragment: " + file, t);
}
finally
{
@@ -660,7 +686,7 @@
}
catch (Throwable t)
{
- Log.error("Could not marshal: " + file, t);
+ Log.error("RegistryService: Could not marshal: " + file, t);
}
finally
{
@@ -758,15 +784,15 @@
if (Log.getLogger().isDebugEnabled())
{
- Log.debug("Updating the " + regName + " registry");
- }
+ Log.debug("RegistryService: Updating the " + regName + " registry");
+ }
int count = 0;
Registry registry = get(regName);
if (registry == null)
{
- Log.error("Null " + name + " registry in refresh");
+ Log.error("RegistryService: Null " + name + " registry in refresh");
return;
}
@@ -776,6 +802,19 @@
{
String location = (String) en.nextElement();
RegistryFragment fragment = (RegistryFragment) fragments.get(location);
+ int fragCount = 0;
+
+ if (!fragment.hasChanged())
+ {
+ if ((verbose>2) && Log.getLogger().isDebugEnabled())
+ {
+ Log.debug("RegistryService: Skipping fragment " + location);
+ }
+ continue;
+ }
+
+ //the fragment has some changes, iterate over its entries...
+
Vector entries = fragment.getEntries(regName);
//... if it has entries related to this regsistry,
@@ -789,35 +828,55 @@
// update or add the entry in the registry
try
{
- if (Log.getLogger().isDebugEnabled())
- {
- Log.debug("Adding entry " + entry.getName() + " of
class " + entry.getClass() + " to registry " + name);
- }
-
if (registry.hasEntry(entry.getName()))
{
- registry.setEntry(entry);
+ if (registry.getEntry(entry.getName()).equals(entry))
+ {
+ if ((verbose>2) && Log.getLogger().isDebugEnabled())
+ {
+ Log.debug("RegistryService: No changes to entry
" + entry.getName());
+ }
+ }
+ else
+ {
+ if ((verbose>1) && Log.getLogger().isDebugEnabled())
+ {
+ Log.debug("RegistryService: Updating entry " +
entry.getName() + " of class " + entry.getClass() + " to registry " + name);
+ }
+
+ registry.setEntry(entry);
+ // Initialize the entry index
+ this.entryIndex.put(entry.getName(), location);
+ ++fragCount;
+ }
}
else
{
registry.addEntry(entry);
+ // Initialize the entry index
+ this.entryIndex.put(entry.getName(), location);
+ ++fragCount;
+
+ if ((verbose>1) && Log.getLogger().isDebugEnabled())
+ {
+ Log.debug("RegistryService: Adding entry " +
entry.getName() + " of class " + entry.getClass() + " to registry " + name);
+ }
}
- // Initialize the entry index
- this.entryIndex.put(entry.getName(), location);
- ++count;
}
catch (RegistryException e)
{
- Log.error("RegistryException while adding " +
entry.getName() + "from " + location, e);
+ Log.error("RegistryService: RegistryException while adding
" + entry.getName() + "from " + location, e);
}
}
}
+
+ count+=fragCount;
}
- if (Log.getLogger().isDebugEnabled())
+ if ((verbose>1) && Log.getLogger().isDebugEnabled())
{
- Log.debug("Merged " + count + " entries into the " + name);
- }
+ Log.debug("RegistryService: Merged " + count + " entries into the " +
name);
+ }
}
1.3 +11 -5
jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/FileRegistry.java
Index: FileRegistry.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/FileRegistry.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- FileRegistry.java 2 May 2001 14:17:28 -0000 1.2
+++ FileRegistry.java 3 Nov 2002 15:09:47 -0000 1.3
@@ -55,23 +55,29 @@
package org.apache.jetspeed.services.registry;
import java.io.Reader;
+import java.util.Map;
/**
- * Interface for manipulating RegistryFragments in a fragment based
+ * Interface for manipulating RegistryFragments in a fragment based
* registry implementation.
*
* @author <a href="mailto:raphael@;apache.org">Rapha�l Luta</a>
* @version $Id$
*/
public interface FileRegistry {
-
+
public static final int DEFAULT_REFRESH = 300;
- /** Refresh the state of the registry implementation. Should be called
+ /** Refresh the state of the registry implementation. Should be called
* whenever the underlying fragments are modified
*/
public void refresh();
-
+
+ /**
+ * @return a Map of all fragments keyed by file names
+ */
+ public Map getFragmentMap();
+
/**
* Read and unmarshal a fragment in memory
* @param name the name of this fragment
1.9 +47 -2
jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/RegistryFragment.java
Index: RegistryFragment.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/RegistryFragment.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- RegistryFragment.java 30 Oct 2002 15:52:39 -0000 1.8
+++ RegistryFragment.java 3 Nov 2002 15:09:47 -0000 1.9
@@ -67,7 +67,52 @@
* @author <a href="mailto:raphael@;apache.org">Rapha�l Luta</a>
* @version $Id$
*/
-public class RegistryFragment extends Hashtable implements java.io.Serializable {
+public class RegistryFragment extends Hashtable implements java.io.Serializable
+{
+
+ /** this flag is used to mark this fragment has some changes that are
+ * not yet persisted to disk
+ */
+ private transient boolean dirty = false;
+
+ /** this flag is used to mark that this fragment needs to updated to
+ * incorporated changes from its disk state
+ */
+ private transient boolean changed = false;
+
+ /** @return true if this fragment has some unpersisted changes
+ */
+ public boolean isDirty()
+ {
+ return this.dirty;
+ }
+
+ /** Sets the dirty flag indicating wether this fragment has some
+ * uncommitted changes
+ *
+ * @param value the new dirty state for this fragment
+ */
+ public void setDirty(boolean value)
+ {
+ this.dirty = value;
+ }
+
+ /** @return true if this fragment has some persisted changes that need loading
+ */
+ public boolean hasChanged()
+ {
+ return this.changed;
+ }
+
+ /** Sets the changed flag indicating wether this fragment has some
+ * changes to load
+ *
+ * @param value the new dirty state for this fragment
+ */
+ public void setChanged(boolean value)
+ {
+ this.changed = value;
+ }
/** @return the entries stored in this Fragment that are suitable
* for the requested registry
1.6 +153 -70
jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/RegistryWatcher.java
Index: RegistryWatcher.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/RegistryWatcher.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- RegistryWatcher.java 4 Jul 2002 00:01:09 -0000 1.5
+++ RegistryWatcher.java 3 Nov 2002 15:09:47 -0000 1.6
@@ -59,10 +59,11 @@
import java.io.FileFilter;
import java.util.Enumeration;
import java.util.Hashtable;
-
+import java.util.Iterator;
+import java.util.Map;
/**
- * Monitors a Registry directory and notifies the associated Registry
+ * Monitors a Registry directory and notifies the associated Registry
* of file updates.
*
* @author <a href="mailto:raphael@;apache.org">Rapha�l Luta</a>
@@ -73,7 +74,7 @@
/** Minimum scan rate for evaluating file refresh */
public static final int SCAN_RATE = 60;
-
+
/**
The files monitored by this watcher
*/
@@ -104,7 +105,7 @@
*/
public RegistryWatcher() {
setDaemon(true);
- setPriority(Thread.MIN_PRIORITY);
+ setPriority(Thread.MIN_PRIORITY);
}
/** Modifies the subscriber to this Watcher
@@ -126,13 +127,13 @@
}
catch (Exception e)
{
- Log.error("Can't remove fragment", e);
+ Log.error("RegistryWatcher: Can't remove fragment", e);
}
}
}
-
+
this.subscriber = registry;
-
+
if (subscriber!=null)
{
Enumeration en = files.keys();
@@ -144,19 +145,19 @@
}
catch (Exception e)
{
- Log.error("Can't load fragment", e);
+ Log.error("RegistryWatcher: Can't load fragment", e);
}
}
}
}
}
-
+
/** @return the subscriber to this watcher */
public FileRegistry getSubscriber()
{
return this.subscriber;
}
-
+
/** Sets the refresh rate for this watcher
* @param refresh the refresh rate in seconds
*/
@@ -164,27 +165,27 @@
{
this.refreshRate = (( refresh > SCAN_RATE ) ? refresh : SCAN_RATE) * 1000;
}
-
+
/** @return the refresh rate, in seconds, of this watcher */
public long getRefreshRate()
{
return refreshRate / 1000;
}
-
- /** Sets the file filter for selecting the registry files
+
+ /** Sets the file filter for selecting the registry files
* @param filter the file filter to use
*/
public void setFilter(FileFilter filter)
{
this.filter = filter;
}
-
+
/** @return the file filter used by this watcher instance */
public FileFilter getFilter()
{
return filter;
}
-
+
/** Change the base file or directory to be monitored by this watcher
*
* @param f the file or directory to monitor
@@ -204,7 +205,7 @@
}
catch (Exception e)
{
- Log.error("Can't remove fragment", e);
+ Log.error("RegistryWatcher: Can't remove fragment", e);
}
}
}
@@ -212,7 +213,7 @@
findFiles(f);
}
}
-
+
/**
* Refresh the monitored file list
*
@@ -228,12 +229,12 @@
if (f.isDirectory())
{
-
+
if (filter != null)
contents = f.listFiles(filter);
else
contents = f.listFiles();
-
+
if (contents!=null)
{
for (int i=0; i< contents.length; i++)
@@ -248,19 +249,19 @@
}
catch (Exception e)
{
- Log.error("Can't load fragment", e);
+ Log.error("RegistryWatcher: Can't load fragment",
e);
}
}
}
}
}
- }
+ }
}
-
+
/**
- * <p>Main routine for the monitor which periodically checks whether
+ * <p>Main routine for the monitor which periodically checks whether
* the filex have been modified.</p>
- * The algorithm used does not guarantee a constant refresh rate
+ * The algorithm used does not guarantee a constant refresh rate
* between invocations.
*/
public void run()
@@ -269,71 +270,153 @@
{
while(!done)
{
- Log.debug( "RegistryWatcher: Checking for updated files.");
- Enumeration en = files.keys();
boolean needRefresh = false;
- while(en.hasMoreElements())
+
+ synchronized (subscriber)
{
- try
+ Map fragments = subscriber.getFragmentMap();
+
+ if (Log.getLogger().isDebugEnabled())
{
- File f = (File)en.nextElement();
- long modified = ((Long)files.get(f)).longValue();
+ Log.debug( "RegistryWatcher: Saving dirty fragments.");
+ }
- if (!f.exists())
+ Iterator i = fragments.keySet().iterator();
+ while(i.hasNext())
+ {
+ try
{
- files.remove(f);
+ String filename = (String)i.next();
+ RegistryFragment fragment =
(RegistryFragment)subscriber.getFragmentMap().get(filename);
+
+ // if fragment has some uncommitted changes
+ if (fragment.isDirty())
+ {
+ //save it to disk
+ subscriber.saveFragment(filename);
+
+ if (Log.getLogger().isDebugEnabled())
+ {
+ Log.debug( "RegistryWatcher: Saved " +
filename);
+ }
+
+ //and update the stored timestamp
+ Enumeration en = files.keys();
+ while(en.hasMoreElements())
+ {
+ File f = (File)en.nextElement();
+ if (filename.equals(f.getCanonicalPath()))
+ {
+ files.put(f,new Long(f.lastModified()));
+ }
+ }
+ }
}
- else
+ catch (Exception e)
{
- if (f.lastModified() > modified)
+ Log.error("RegistryWatcher: exception during update",e);
+ }
+ }
+
+ if (Log.getLogger().isDebugEnabled())
+ {
+ Log.debug( "RegistryWatcher: Checking for updated files.");
+ }
+
+ Enumeration en = files.keys();
+ while(en.hasMoreElements())
+ {
+ try
+ {
+ File f = (File)en.nextElement();
+ long modified = ((Long)files.get(f)).longValue();
+
+ if (!f.exists())
+ {
+ files.remove(f);
+ }
+ else
{
- files.put(f,new Long(f.lastModified()));
- if (f.isDirectory())
+ if (f.lastModified() > modified)
{
- File[] contents = null;
-
- if (filter != null)
- contents = f.listFiles(filter);
- else
- contents = f.listFiles();
-
- if (contents!=null)
+ files.put(f,new Long(f.lastModified()));
+
+ if (f.isDirectory())
{
- for (int i=0; i< contents.length; i++)
+ File[] contents = null;
+
+ if (filter != null)
+ {
+ contents = f.listFiles(filter);
+ }
+ else
{
- if (files.get(contents[i])==null)
+ contents = f.listFiles();
+ }
+
+ if (contents!=null)
+ {
+ for (int idx=0; idx< contents.length;
idx++)
{
- files.put(contents[i],new
Long(contents[i].lastModified()));
-
- if (subscriber!=null)
+ if (files.get(contents[idx])==null)
{
-
subscriber.loadFragment(contents[i].getCanonicalPath());
+ files.put(contents[idx],new
Long(contents[idx].lastModified()));
+
+ if (subscriber!=null)
+ {
+
subscriber.loadFragment(contents[idx].getCanonicalPath());
+ }
}
}
}
}
+ else
+ {
+
subscriber.loadFragment(f.getCanonicalPath());
+ }
+
+ if (Log.getLogger().isDebugEnabled())
+ {
+ Log.debug("RegistryWatcher: Refreshing
because "
+ + f.getCanonicalPath()
+ + " was modified.("
+ + f.lastModified()
+ + " "
+ + modified
+ + ")");
+ }
+
+ RegistryFragment frag =
(RegistryFragment)fragments.get(f.getCanonicalPath());
+
+ if (frag!=null)
+ {
+ frag.setChanged(true);
+ }
+
+ needRefresh = true;
}
- else
- {
- subscriber.loadFragment(f.getCanonicalPath());
- }
- Log.debug("RegistryWatcher: Refreshing because "
- + f.getCanonicalPath() + " was modified.");
- needRefresh = true;
}
}
+ catch (Exception e)
+ {
+ Log.error("RegistryWatcher: exception during update",e);
+ }
}
- catch (Exception e)
+
+ if (needRefresh)
{
- Log.error("RegistryWatcher: exception during update",e);
+ subscriber.refresh();
+ needRefresh = false;
+ }
+
+ // make sure to reset the state of all fragments
+ i = fragments.keySet().iterator();
+ while(i.hasNext())
+ {
+ RegistryFragment frag =
(RegistryFragment)fragments.get((String)i.next());
+ frag.setDirty(false);
+ frag.setChanged(false);
}
- }
-
-
- if (needRefresh)
- {
- subscriber.refresh();
- needRefresh = false;
}
sleep( refreshRate );
@@ -341,12 +424,12 @@
}
catch (InterruptedException e)
{
- Log.error("RegistryWatcher stopping monitor: ");
+ Log.error("RegistryWatcher: Stopping monitor: ");
Log.error(e);
return;
}
}
-
+
/**
* Mark that the watching thread should be stopped
*/
@@ -355,5 +438,5 @@
done = true;
Log.info("RegistryWatcher: Watching thread stop requested");
}
-
+
}
--
To unsubscribe, e-mail: <mailto:jetspeed-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:jetspeed-dev-help@;jakarta.apache.org>