[jboss-cvs] JBossCache/src/org/jboss/cache ...
Manik Surtani
msurtani at jboss.com
Wed Nov 15 10:16:40 EST 2006
User: msurtani
Date: 06/11/15 10:16:40
Modified: src/org/jboss/cache Region.java TreeCache.java
RegionImpl.java RegionManager.java
Log:
Updated to fix failures after patching up region managers
Revision Changes Path
1.7 +2 -2 JBossCache/src/org/jboss/cache/Region.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Region.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/Region.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- Region.java 14 Nov 2006 14:17:11 -0000 1.6
+++ Region.java 15 Nov 2006 15:16:40 -0000 1.7
@@ -88,7 +88,7 @@
*
* @see #unmarkNodeCurrentlyInUse(Fqn)
*/
- void markNodeCurrentlyInUse(long timeout);
+ void markNodeCurrentlyInUse(Fqn fqn, long timeout);
/**
* Add an event to the eviction queue indicating that a node is no longer in use.
@@ -97,7 +97,7 @@
*
* @see #markNodeCurrentlyInUse(Fqn, long)
*/
- void unmarkNodeCurrentlyInUse();
+ void unmarkNodeCurrentlyInUse(Fqn fqn);
Fqn getFqn();
}
1.269 +327 -77 JBossCache/src/org/jboss/cache/TreeCache.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TreeCache.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TreeCache.java,v
retrieving revision 1.268
retrieving revision 1.269
diff -u -b -r1.268 -r1.269
--- TreeCache.java 14 Nov 2006 19:56:09 -0000 1.268
+++ TreeCache.java 15 Nov 2006 15:16:40 -0000 1.269
@@ -39,8 +39,8 @@
import org.jboss.cache.notifications.Notifier;
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.statetransfer.StateTransferManager;
-import org.jboss.util.stream.MarshalledValueInputStream;
import org.jboss.util.stream.MarshalledValueOutputStream;
+import org.jboss.util.stream.MarshalledValueInputStream;
import org.jgroups.Address;
import org.jgroups.Channel;
import org.jgroups.ChannelClosedException;
@@ -72,7 +72,6 @@
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -83,6 +82,7 @@
import java.util.Map;
import java.util.Set;
import java.util.Vector;
+import java.util.Arrays;
/**
* A tree-like structure that is replicated across several members. Updates are
@@ -94,7 +94,7 @@
* @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
* @author Brian Stansberry
* @author Daniel Huang (dhuang at jboss.org)
- * @version $Id: TreeCache.java,v 1.268 2006/11/14 19:56:09 vblagojevic Exp $
+ * @version $Id: TreeCache.java,v 1.269 2006/11/15 15:16:40 msurtani Exp $
* <p/>
* @see <a href="http://labs.jboss.com/portal/jbosscache/docs">JBossCache doc</a>
*/
@@ -111,7 +111,7 @@
*/
protected DataNode root = NodeFactory.getInstance().createRootDataNode(NodeFactory.NODE_TYPE_TREENODE, this);
- private RegionManager regionManager = null;
+ private RegionManager regionManager = new RegionManager(this);
final static Object NULL = new Object();
@@ -156,8 +156,6 @@
*/
private final Map lock_table = new ConcurrentHashMap();
- protected boolean usingEviction = false;
-
/**
* Set<Fqn> of Fqns of the topmost node of internal regions that should
* not included in standard state transfers.
@@ -260,6 +258,12 @@
private ThreadLocal<InvocationContext> invocationContextContainer = new ThreadLocal<InvocationContext>();
+ /**
+ * Set of Fqns of nodes that are currently being processed by
+ * activateReqion or inactivateRegion. Requests for these fqns
+ * will be ignored by _getState().
+ */
+ protected final Set activationChangeNodes = Collections.synchronizedSet(new HashSet());
public boolean started;
public Configuration getConfiguration()
@@ -288,7 +292,6 @@
{
notifier = new Notifier(this);
this.configuration = configuration;
- regionManager = new RegionManager(this);
}
/**
@@ -297,7 +300,6 @@
public TreeCache() throws Exception
{
notifier = new Notifier(this);
- regionManager = new RegionManager(this);
}
/**
@@ -307,7 +309,6 @@
{
notifier = new Notifier(this);
this.channel = channel;
- regionManager = new RegionManager(this);
}
/**
@@ -466,16 +467,6 @@
return this.evictionInterceptorClass;
}
- public boolean isUsingEviction()
- {
- return this.usingEviction;
- }
-
- public void setIsUsingEviction(boolean usingEviction)
- {
- this.usingEviction = usingEviction;
- }
-
private void setUseReplQueue(boolean flag)
{
if (flag)
@@ -918,13 +909,12 @@
if (configuration.getEvictionConfig() != null
&& configuration.getEvictionConfig().isValidConfig())
{
- //evictionRegionManager_.configure(this);
- if (true) throw new RuntimeException("Fixme: configure the region manager for evictions");
- this.usingEviction = true;
+ regionManager.setEvictionConfig(configuration.getEvictionConfig());
+ regionManager.setUsingEvictions(true);
}
else
{
- this.usingEviction = false;
+ regionManager.setUsingEvictions(false);
log.debug("Not using an EvictionPolicy");
}
}
@@ -1012,6 +1002,133 @@
}
/**
+ * Causes the cache to transfer state for the subtree rooted at
+ * <code>subtreeFqn</code> and to begin accepting replication messages
+ * for that subtree.
+ * <p/>
+ * <strong>NOTE:</strong> This method will cause the creation of a node
+ * in the local tree at <code>subtreeFqn</code> whether or not that
+ * node exists anywhere else in the cluster. If the node does not exist
+ * elsewhere, the local node will be empty. The creation of this node will
+ * not be replicated.
+ *
+ * @param subtreeFqn Fqn string indicating the uppermost node in the
+ * portion of the tree that should be activated.
+ * @throws RegionNotEmptyException if the node <code>subtreeFqn</code>
+ * exists and has either data or children
+ */
+ public void activateRegion(String subtreeFqn) throws RegionNameConflictException, CacheException
+ {
+ Fqn fqn = Fqn.fromString(subtreeFqn);
+
+ // Check whether the node already exists and has data
+ DataNode subtreeRoot = findNode(fqn);
+ if (!(isNodeEmpty(subtreeRoot)))
+ {
+ throw new RegionNotEmptyException("Node " + subtreeRoot.getFqn() + " already exists and is not empty");
+ }
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("activating " + fqn);
+ }
+
+ try
+ {
+
+ // Add this fqn to the set of those we are activating
+ // so calls to _getState for the fqn can return quickly
+ activationChangeNodes.add(fqn);
+
+ Region region = regionManager.getRegion(fqn, true);
+
+ // If a classloader is registered for the node's region, use it
+ ClassLoader cl = region.getClassLoader();
+
+ // Request partial state from the cluster and integrate it
+ if (buddyManager == null)
+ {
+ // Get the state from any node that has it and put it
+ // in the main tree
+ if (subtreeRoot == null)
+ {
+ // We'll update this node with the state we receive
+ subtreeRoot = createSubtreeRootNode(fqn);
+ }
+
+ Object[] mbrArray = getMembers().toArray();
+ getStateTransferManager().loadState(subtreeRoot.getFqn(), subtreeRoot, mbrArray, cl);
+ }
+ else
+ {
+ // Get the state from each DataOwner and integrate in their
+ // respective buddy backup tree
+ List buddies = buddyManager.getBuddyAddresses();
+ for (Iterator it = buddies.iterator(); it.hasNext();)
+ {
+ Address buddy = (Address) it.next();
+ Object[] sources = {buddy};
+ Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, BuddyManager.getGroupNameFromAddress(buddy));
+ Fqn buddyRoot = new Fqn(base, fqn);
+ subtreeRoot = findNode(buddyRoot);
+ if (subtreeRoot == null)
+ {
+ // We'll update this node with the state we receive
+ subtreeRoot = createSubtreeRootNode(buddyRoot);
+ }
+ getStateTransferManager().loadState(fqn, subtreeRoot, sources, cl);
+ }
+ }
+
+ region.activate();
+
+ }
+ catch (Throwable t)
+ {
+ log.error("failed to activate " + subtreeFqn, t);
+
+ // "Re-deactivate" the region
+ try
+ {
+ inactivateRegion(subtreeFqn);
+ }
+ catch (Exception e)
+ {
+ log.error("failed inactivating " + subtreeFqn, e);
+ // just swallow this one and throw the first one
+ }
+
+ // Throw the exception on, wrapping if necessary
+ if (t instanceof RegionNameConflictException)
+ {
+ throw(RegionNameConflictException) t;
+ }
+ else if (t instanceof RegionNotEmptyException)
+ {
+ throw(RegionNotEmptyException) t;
+ }
+ else if (t instanceof CacheException)
+ {
+ throw(CacheException) t;
+ }
+ else
+ {
+ throw new CacheException(t.getClass().getName() + " " +
+ t.getLocalizedMessage(), t);
+ }
+ }
+ finally
+ {
+ activationChangeNodes.remove(fqn);
+ }
+ }
+
+ public boolean isActivatingDeactivating(Fqn fqn)
+ {
+ return activationChangeNodes.contains(fqn);
+ }
+
+ /**
* Returns whether the given node is empty; i.e. has no key/value pairs
* in its data map and has no children.
*
@@ -1019,7 +1136,7 @@
* @return <code>true</code> if <code>node</code> is <code>null</code> or
* empty; <code>false</code> otherwise.
*/
- protected boolean isNodeEmpty(DataNode node)
+ private boolean isNodeEmpty(DataNode node)
{
boolean empty = true;
if (node != null)
@@ -1100,6 +1217,138 @@
}
/**
+ * Causes the cache to stop accepting replication events for the subtree
+ * rooted at <code>subtreeFqn</code> and evict all nodes in that subtree.
+ *
+ * @param subtreeFqn Fqn string indicating the uppermost node in the
+ * portion of the tree that should be activated.
+ * @throws RegionNameConflictException if <code>subtreeFqn</code> indicates
+ * a node that is part of another
+ * subtree that is being specially
+ * managed (either by activate/inactiveRegion()
+ * or by registerClassLoader())
+ * @throws CacheException if there is a problem evicting nodes
+ * @throws IllegalStateException if {@link Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
+ */
+ public void inactivateRegion(String subtreeFqn) throws RegionNameConflictException, CacheException
+ {
+ if (!configuration.isUseRegionBasedMarshalling())
+ {
+ throw new IllegalStateException("TreeCache.deactivate(). useRegionBasedMarshalling flag is not set!");
+ }
+
+ Fqn fqn = Fqn.fromString(subtreeFqn);
+ DataNode parent = null;
+ DataNode subtreeRoot = null;
+ boolean parentLocked = false;
+ boolean subtreeLocked = false;
+ try
+ {
+ // Record that this fqn is in status change, so can't provide state
+ activationChangeNodes.add(fqn);
+
+ boolean inactive = marshaller_.isInactive(subtreeFqn);
+ if (!inactive)
+ {
+ regionManager.deactivate(subtreeFqn);
+ }
+
+ // Create a list with the Fqn in the main tree and any buddy backup trees
+ ArrayList list = new ArrayList();
+ list.add(fqn);
+ if (buddyManager != null)
+ {
+ Set buddies = getChildrenNames(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
+ if (buddies != null)
+ {
+ for (Iterator it = buddies.iterator(); it.hasNext();)
+ {
+ Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, it.next());
+ list.add(new Fqn(base, fqn));
+ }
+ }
+ }
+
+ // Remove the subtree from the main tree and any buddy backup trees
+ for (Iterator it = list.iterator(); it.hasNext();)
+ {
+ Fqn subtree = (Fqn) it.next();
+ subtreeRoot = findNode(subtree);
+ if (subtreeRoot != null)
+ {
+ // Acquire locks
+ Object owner = getOwnerForLock();
+ subtreeRoot.acquireAll(owner, stateFetchTimeout, DataNode.LockType.WRITE);
+ subtreeLocked = true;
+
+ // Lock the parent, as we're about to write to it
+ parent = (DataNode) subtreeRoot.getParent();
+ if (parent != null)
+ {
+ parent.acquire(owner, stateFetchTimeout, DataNode.LockType.WRITE);
+ parentLocked = true;
+ }
+
+ // Remove the subtree
+ _evictSubtree(subtree);
+
+ // Release locks
+ if (parent != null)
+ {
+ log.debug("forcing release of locks in parent");
+ parent.releaseAllForce();
+ }
+
+ parentLocked = false;
+
+ log.debug("forcing release of all locks in subtree");
+ subtreeRoot.releaseAllForce();
+ subtreeLocked = false;
+ }
+ }
+ }
+ catch (InterruptedException ie)
+ {
+ throw new CacheException("Interrupted while acquiring lock", ie);
+ }
+ finally
+ {
+ // If we didn't succeed, undo the marshalling change
+ // NO. Since we inactivated, we may have missed changes
+ //if (!success && !inactive)
+ // marshaller_.activate(subtreeFqn);
+
+ // If necessary, release locks
+ if (parentLocked)
+ {
+ log.debug("forcing release of locks in parent");
+ try
+ {
+ parent.releaseAllForce();
+ }
+ catch (Throwable t)
+ {
+ log.error("failed releasing locks", t);
+ }
+ }
+ if (subtreeLocked)
+ {
+ log.debug("forcing release of all locks in subtree");
+ try
+ {
+ subtreeRoot.releaseAllForce();
+ }
+ catch (Throwable t)
+ {
+ log.error("failed releasing locks", t);
+ }
+ }
+
+ activationChangeNodes.remove(fqn);
+ }
+ }
+
+ /**
* Evicts the node at <code>subtree</code> along with all descendant nodes.
*
* @param subtree Fqn indicating the uppermost node in the
@@ -3367,14 +3616,19 @@
public void setState(byte[] new_state)
{
+ try
+ {
+
if (new_state == null)
{
my_log.debug("transferred state is null (may be first member in cluster)");
return;
}
- try
+ else
{
getStateTransferManager().setState(new_state, Fqn.ROOT, null);
+ }
+
isStateSet = true;
}
catch (Throwable t)
@@ -3462,14 +3716,16 @@
public void setState(InputStream istream)
{
+ try
+ {
+
if (istream == null)
{
my_log.debug("stream is null (may be first member in cluster)");
return;
}
- try
- {
getStateTransferManager().setState(istream, Fqn.ROOT, null);
+
isStateSet = true;
}
catch (Throwable t)
@@ -3492,6 +3748,7 @@
stateLock.notifyAll();
}
}
+
}
public void setState(String state_id, byte[] state)
@@ -3902,13 +4159,6 @@
public RegionManager getRegionManager()
{
- if (regionManager == null)
- {
- synchronized (this)
- {
- if (regionManager == null) regionManager = new RegionManager(this);
- }
- }
return regionManager;
}
1.9 +24 -10 JBossCache/src/org/jboss/cache/RegionImpl.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: RegionImpl.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/RegionImpl.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- RegionImpl.java 14 Nov 2006 19:56:09 -0000 1.8
+++ RegionImpl.java 15 Nov 2006 15:16:40 -0000 1.9
@@ -31,7 +31,7 @@
BoundedLinkedQueue nodeEventQueue_;
int checkCapacityCount = 0;
int capacityWarnThreshold = 0;
- EvictionRegionConfig configuration;
+ EvictionRegionConfig configuration = new EvictionRegionConfig();
EvictionPolicy policy;
/**
@@ -72,13 +72,13 @@
public void activate()
{
- regionManager.activateRegion(fqn.toString());
+ regionManager.activate(fqn.toString());
active = true;
}
public void deactivate()
{
- regionManager.inactivateRegion(fqn.toString());
+ regionManager.deactivate(fqn.toString());
active = false;
}
@@ -100,14 +100,14 @@
// -------- eviction stuff -----
- public void markNodeCurrentlyInUse(long timeout)
+ public void markNodeCurrentlyInUse(Fqn fqn, long timeout)
{
EvictedEventNode markUse = new EvictedEventNode(fqn, NodeEventType.MARK_IN_USE_EVENT);
markUse.setInUseTimeout(timeout);
putNodeEvent(markUse);
}
- public void unmarkNodeCurrentlyInUse()
+ public void unmarkNodeCurrentlyInUse(Fqn fqn)
{
EvictedEventNode markNoUse = new EvictedEventNode(fqn, NodeEventType.UNMARK_USE_EVENT);
putNodeEvent(markNoUse);
@@ -159,6 +159,7 @@
public void putNodeEvent(EvictedEventNode event)
{
+ if (nodeEventQueue_ == null) createQueue();
try
{
// Don't check capacity every time as this is an expensive operation for
@@ -250,10 +251,23 @@
public void setEvictionPolicy(EvictionPolicyConfig evictionPolicyConfig)
{
- //To change body of implemented methods use File | Settings | File Templates.
+ configuration.setEvictionPolicyConfig(evictionPolicyConfig);
+ policy = createPolicy(evictionPolicyConfig.getEvictionPolicyClass());
}
-
-
-
+ private EvictionPolicy createPolicy(String className)
+ {
+ try
+ {
+ if (log.isTraceEnabled()) log.trace("Instantiating " + className);
+ EvictionPolicy ep = (EvictionPolicy) Class.forName(className).newInstance();
+ ep.configure(regionManager.treeCache);
+ return ep;
+ }
+ catch (Exception e)
+ {
+ log.fatal("Unable to instantiate eviction policy class " + className, e);
+ return null;
+ }
+ }
}
1.6 +73 -302 JBossCache/src/org/jboss/cache/RegionManager.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: RegionManager.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/RegionManager.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- RegionManager.java 14 Nov 2006 19:56:09 -0000 1.5
+++ RegionManager.java 15 Nov 2006 15:16:40 -0000 1.6
@@ -1,23 +1,19 @@
package org.jboss.cache;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.eviction.RegionNameConflictException;
+
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.buddyreplication.BuddyManager;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.marshall.RegionNameConflictException;
-import org.jboss.cache.marshall.VersionAwareMarshaller;
-import org.jgroups.Address;
-
/**
* Encapsulates the concept of a {@link Region}, and manages instances of such regions.
*
@@ -27,21 +23,35 @@
public class RegionManager
{
/**
+ * The default region used in XML configuration files when defining eviction policies. Any
+ * eviction settings bound under this 'default' Fqn is appplied to {@link org.jboss.cache.Fqn#ROOT} internally so
+ * any region that is not explicitly defined comes under the settings defined for this default.
+ */
+ public static final Fqn DEFAULT_REGION = Fqn.fromString("/_default_");
+ /**
* A registry of regions that have been defined.
*/
Map<Fqn, Region> regionsRegistry = new ConcurrentHashMap<Fqn, Region>();
boolean defaultInactive;
private Log log = LogFactory.getLog(RegionManager.class);
+ TreeCache treeCache;
+ private boolean usingEvictions;
+ private EvictionConfig evictionConfig;
- protected final Set activationChangeNodes = Collections.synchronizedSet(new HashSet());
- TreeCache cache;
- public RegionManager(){}
+ public RegionManager()
+ {
+ }
+
+ public boolean isUsingEvictions()
+ {
+ return usingEvictions;
+ }
- public RegionManager(TreeCache cache)
+ public RegionManager(TreeCache treeCache)
{
- this.cache = cache;
+ this.treeCache = treeCache;
}
public boolean isDefaultInactive()
@@ -54,6 +64,8 @@
this.defaultInactive = defaultInactive;
}
+
+
/**
* Helper utility that checks for a classloader registered for the
* given Fqn, and if found sets it as the TCCL. If the given Fqn is
@@ -98,20 +110,29 @@
public Region getRegion(Fqn fqn, boolean createIfAbsent)
{
+ Fqn fqnToUse = fqn;
+ if (DEFAULT_REGION.equals(fqnToUse)) fqnToUse = Fqn.ROOT;
// first see if a region for this specific Fqn exists
- if (regionsRegistry.containsKey(fqn)) return regionsRegistry.get(fqn);
+ if (regionsRegistry.containsKey(fqnToUse)) return regionsRegistry.get(fqnToUse);
// if not, attempt to create one ...
if (createIfAbsent)
{
- Region r = new RegionImpl(fqn, this);
- regionsRegistry.put(fqn, r);
+ Region r = new RegionImpl(fqnToUse, this);
+ regionsRegistry.put(fqnToUse, r);
return r;
}
+ else
+ {
+ // first test if the default region has been defined. If not, and if eviction regions
+ // are in use, throw an exception since it is required.
+ if (isUsingEvictions() && !regionsRegistry.containsKey(Fqn.ROOT))
+ throw new RuntimeException("No default eviction region defined!");
+ }
// else try and find a parent which has a defined region, may return null if nothing is defined.
Region r = null;
- Fqn nextFqn = fqn;
+ Fqn nextFqn = fqnToUse;
while (r == null)
{
@@ -121,7 +142,6 @@
}
return r;
-
}
/**
@@ -224,282 +244,6 @@
}
/**
- * Causes the cache to transfer state for the subtree rooted at
- * <code>subtreeFqn</code> and to begin accepting replication messages
- * for that subtree.
- * <p/>
- * <strong>NOTE:</strong> This method will cause the creation of a node
- * in the local tree at <code>subtreeFqn</code> whether or not that
- * node exists anywhere else in the cluster. If the node does not exist
- * elsewhere, the local node will be empty. The creation of this node will
- * not be replicated.
- *
- * @param subtreeFqn Fqn string indicating the uppermost node in the
- * portion of the tree that should be activated.
- * @throws RegionNotEmptyException if the node <code>subtreeFqn</code>
- * exists and has either data or children
- */
- public void activateRegion(String subtreeFqn) throws CacheException
- {
- Fqn fqn = Fqn.fromString(subtreeFqn);
-
- // Check whether the node already exists and has data
- DataNode subtreeRoot = cache.findNode(fqn);
- if (!(cache.isNodeEmpty(subtreeRoot)))
- {
- throw new RegionNotEmptyException("Node " + subtreeRoot.getFqn() + " already exists and is not empty");
- }
-
- if(isActivatingDeactivating(fqn))
- {
- throw new CacheException("Region " + subtreeRoot.getFqn() + " is already being activated/deactivated");
- }
-
- if (log.isDebugEnabled())
- {
- log.debug("activating " + fqn);
- }
-
- try
- {
-
- // Add this fqn to the set of those we are activating
- // so calls to _getState for the fqn can return quickly
- activationChangeNodes.add(fqn);
-
- Region region = getRegion(fqn, true);
-
- // If a classloader is registered for the node's region, use it
- ClassLoader cl = region.getClassLoader();
-
- BuddyManager buddyManager = cache.getBuddyManager();
- // Request partial state from the cluster and integrate it
- if (buddyManager == null)
- {
- // Get the state from any node that has it and put it
- // in the main tree
- if (subtreeRoot == null)
- {
- // We'll update this node with the state we receive
- subtreeRoot = cache.createSubtreeRootNode(fqn);
- }
-
- Address [] groupMembers = null;
- Vector<Address> members = cache.getMembers();
- synchronized (members)
- {
- groupMembers = members.toArray(new Address[members.size()]);
- }
- if (groupMembers.length < 2)
- {
- if (log.isDebugEnabled())
- log.debug("No nodes able to give state");
- }
- else
- {
- cache.fetchPartialState(groupMembers, subtreeRoot.getFqn());
- }
- }
- else
- {
- // Get the state from each DataOwner and integrate in their
- // respective buddy backup tree
- List buddies = buddyManager.getBuddyAddresses();
- for (Iterator it = buddies.iterator(); it.hasNext();)
- {
- Address buddy = (Address) it.next();
- Object sources[] = new Object[]{buddy};
- Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, BuddyManager.getGroupNameFromAddress(buddy));
- Fqn buddyRoot = new Fqn(base, fqn);
- subtreeRoot = cache.findNode(buddyRoot);
- if (subtreeRoot == null)
- {
- // We'll update this node with the state we receive
- subtreeRoot = cache.createSubtreeRootNode(buddyRoot);
- }
- cache.fetchPartialState(sources, subtreeRoot.getFqn());
- }
- }
- }
- catch (Throwable t)
- {
- log.error("failed to activate " + subtreeFqn, t);
-
- // "Re-deactivate" the region
- try
- {
- inactivateRegion(subtreeFqn);
- }
- catch (Exception e)
- {
- log.error("failed inactivating " + subtreeFqn, e);
- // just swallow this one and throw the first one
- }
-
- // Throw the exception on, wrapping if necessary
- if (t instanceof RegionNotEmptyException)
- {
- throw(RegionNotEmptyException) t;
- }
- else if (t instanceof CacheException)
- {
- throw(CacheException) t;
- }
- else
- {
- throw new CacheException(t.getClass().getName() + " " +
- t.getLocalizedMessage(), t);
- }
- }
- finally
- {
- activationChangeNodes.remove(fqn);
- }
- }
-
- /**
- * Causes the cache to stop accepting replication events for the subtree
- * rooted at <code>subtreeFqn</code> and evict all nodes in that subtree.
- *
- * @param subtreeFqn Fqn string indicating the uppermost node in the
- * portion of the tree that should be activated.
- * @throws RegionNameConflictException if <code>subtreeFqn</code> indicates
- * a node that is part of another
- * subtree that is being specially
- * managed (either by activate/inactiveRegion()
- * or by registerClassLoader())
- * @throws CacheException if there is a problem evicting nodes
- * @throws IllegalStateException if {@link Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
- */
- public void inactivateRegion(String subtreeFqn) throws CacheException
- {
- Fqn fqn = Fqn.fromString(subtreeFqn);
- DataNode parent = null;
- DataNode subtreeRoot = null;
- boolean parentLocked = false;
- boolean subtreeLocked = false;
-
- if(isActivatingDeactivating(fqn))
- {
- throw new CacheException("Region " + subtreeRoot.getFqn() + " is already being activated/deactivated");
- }
-
- try
- {
- // Record that this fqn is in status change, so can't provide state
- activationChangeNodes.add(fqn);
-
- VersionAwareMarshaller marshaller = cache.getMarshaller();
- boolean inactive = marshaller.isInactive(subtreeFqn);
- if (!inactive)
- {
- deactivate(subtreeFqn);
- }
-
- // Create a list with the Fqn in the main tree and any buddy backup trees
- BuddyManager buddyManager = cache.getBuddyManager();
- ArrayList list = new ArrayList();
- list.add(fqn);
-
- if (buddyManager != null)
- {
- Set buddies = cache.getChildrenNames(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
- if (buddies != null)
- {
- for (Iterator it = buddies.iterator(); it.hasNext();)
- {
- Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, it.next());
- list.add(new Fqn(base, fqn));
- }
- }
- }
-
- long stateFetchTimeout = cache.getConfiguration().getLockAcquisitionTimeout() + 5000;
- // Remove the subtree from the main tree and any buddy backup trees
- for (Iterator it = list.iterator(); it.hasNext();)
- {
- Fqn subtree = (Fqn) it.next();
- subtreeRoot = cache.findNode(subtree);
- if (subtreeRoot != null)
- {
- // Acquire locks
- Object owner = cache.getOwnerForLock();
- subtreeRoot.acquireAll(owner, stateFetchTimeout, DataNode.LockType.WRITE);
- subtreeLocked = true;
-
- // Lock the parent, as we're about to write to it
- parent = (DataNode) subtreeRoot.getParent();
- if (parent != null)
- {
- parent.acquire(owner, stateFetchTimeout, DataNode.LockType.WRITE);
- parentLocked = true;
- }
-
- // Remove the subtree
- cache._evictSubtree(subtree);
-
- // Release locks
- if (parent != null)
- {
- log.debug("forcing release of locks in parent");
- parent.releaseAllForce();
- }
-
- parentLocked = false;
-
- log.debug("forcing release of all locks in subtree");
- subtreeRoot.releaseAllForce();
- subtreeLocked = false;
- }
- }
- }
- catch (InterruptedException ie)
- {
- throw new CacheException("Interrupted while acquiring lock", ie);
- }
- finally
- {
- // If we didn't succeed, undo the marshalling change
- // NO. Since we inactivated, we may have missed changes
- //if (!success && !inactive)
- // marshaller_.activate(subtreeFqn);
-
- // If necessary, release locks
- if (parentLocked)
- {
- log.debug("forcing release of locks in parent");
- try
- {
- parent.releaseAllForce();
- }
- catch (Throwable t)
- {
- log.error("failed releasing locks", t);
- }
- }
- if (subtreeLocked)
- {
- log.debug("forcing release of all locks in subtree");
- try
- {
- subtreeRoot.releaseAllForce();
- }
- catch (Throwable t)
- {
- log.error("failed releasing locks", t);
- }
- }
-
- activationChangeNodes.remove(fqn);
- }
- }
-
- public boolean isActivatingDeactivating(Fqn fqn)
- {
- return activationChangeNodes.contains(fqn);
- }
-
- /**
* Overloaded form of {@link #activate(Fqn)}
*
* @param fqn
@@ -597,6 +341,33 @@
return regions;
}
+
+ public void setUsingEvictions(boolean usingEvictions)
+ {
+ this.usingEvictions = usingEvictions;
+ }
+
+ public void setEvictionConfig(EvictionConfig evictionConfig)
+ {
+ this.evictionConfig = evictionConfig;
+ boolean setDefault = false;
+ // create regions for the regions defined in the evictionConfig.
+ for (EvictionRegionConfig erc : evictionConfig.getEvictionRegionConfigs())
+ {
+ Fqn fqn = erc.getRegionFqn();
+ if (log.isTraceEnabled()) log.trace("Creating eviction region " + fqn);
+
+ if (fqn.equals(DEFAULT_REGION))
+ {
+ if (setDefault) throw new ConfigurationException("A default region for evictions has already been set for this cache");
+ if (log.isTraceEnabled()) log.trace("Applying settings for " + DEFAULT_REGION + " to Fqn.ROOT");
+ fqn = Fqn.ROOT;
+ setDefault = true;
+ }
+ Region r = getRegion(fqn, true);
+ r.setEvictionPolicy(erc.getEvictionPolicyConfig());
+ }
+ }
}
@@ -614,7 +385,7 @@
* @author Ben Wang 02-2004
* @author Daniel Huang (dhuang at jboss.org)
* @author Brian Stansberry
- * @version $Id: RegionManager.java,v 1.5 2006/11/14 19:56:09 vblagojevic Exp $
+ * @version $Id: RegionManager.java,v 1.6 2006/11/15 15:16:40 msurtani Exp $
*/
/*public class ERegionManager
{
More information about the jboss-cvs-commits
mailing list