JBoss Cache SVN: r5890 - core/trunk/src/main/java/org/jboss/cache.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-05-27 15:31:25 -0400 (Tue, 27 May 2008)
New Revision: 5890
Modified:
core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
Log:
Better toString
Modified: core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-05-27 14:43:21 UTC (rev 5889)
+++ core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-05-27 19:31:25 UTC (rev 5890)
@@ -230,7 +230,6 @@
public String toString()
{
return "InvocationContext{" +
- "methodCall=" + methodCall +
"transaction=" + transaction +
", globalTransaction=" + globalTransaction +
", optionOverrides=" + optionOverrides +
16 years, 7 months
JBoss Cache SVN: r5889 - in core/trunk/src/main/java/org/jboss/cache: lock and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-05-27 10:43:21 -0400 (Tue, 27 May 2008)
New Revision: 5889
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java
Log:
Fixed broken behaviour
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java 2008-05-27 13:28:31 UTC (rev 5888)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java 2008-05-27 14:43:21 UTC (rev 5889)
@@ -111,14 +111,14 @@
@SuppressWarnings("unchecked")
protected WorkspaceNode lockAndCreateWorkspaceNode(NodeFactory nodeFactory, NodeSPI node, TransactionWorkspace workspace, GlobalTransaction gtx, long timeout)
{
- boolean locked = lockManager.lock(node.getFqn(), READ, gtx, timeout);
+ boolean locked = lockManager.lock(node, READ, gtx, timeout);
if (!locked)
throw new TimeoutException("Unable to lock node " + node.getFqn() + " after timeout " + timeout + " for copying into workspace");
WorkspaceNode wn = nodeFactory.createWorkspaceNode(node, workspace);
- lockManager.unlock(node.getFqn(), gtx);
+ lockManager.unlock(node, gtx);
return wn;
}
Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-27 13:28:31 UTC (rev 5888)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-27 14:43:21 UTC (rev 5889)
@@ -47,6 +47,17 @@
boolean lock(Fqn fqn, LockType lockType, Object owner, long timeout);
/**
+ * As {@link #lock(org.jboss.cache.Fqn, LockType, Object, long)} except that a NodeSPI is passed in instead of an Fqn.
+ *
+ * @param node node to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire the lock for
+ * @param timeout maximum length of time to wait for (in millis)
+ * @return true if the lock was acquired, false otherwise.
+ */
+ boolean lock(NodeSPI node, LockType lockType, Object owner, long timeout);
+
+ /**
* Acquires a lock of type lockType, on a specific Node in the cache, denoted by fqn. This
* method will try for a period of time and give up if it is unable to acquire the required lock. The period of time
* is specified in {@link org.jboss.cache.config.Option#getLockAcquisitionTimeout()} and, if this is unset, the default timeout
@@ -88,18 +99,18 @@
/**
* Releases the lock passed in, held by the specified owner
*
- * @param lock NodeLock to unlock
+ * @param fqn Fqn of the node to unlock
* @param owner lock owner
*/
- void unlock(NodeLock lock, Object owner);
+ void unlock(Fqn fqn, Object owner);
/**
* Releases the lock passed in, held by the specified owner
*
- * @param fqn Fqn of the node to unlock
+ * @param node Node to unlock
* @param owner lock owner
*/
- void unlock(Fqn fqn, Object owner);
+ void unlock(NodeSPI node, Object owner);
/**
* Releases locks present in an invocation context and transaction entry, if one is available.
Modified: core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java 2008-05-27 13:28:31 UTC (rev 5888)
+++ core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java 2008-05-27 14:43:21 UTC (rev 5889)
@@ -60,6 +60,7 @@
private NodeLock acquireLock(NodeSPI node, LockType lockType, Object owner, long timeout)
{
+ if (node == null) return null;
NodeLock lock = node.getLock();
boolean acquired = false;
try
@@ -92,6 +93,12 @@
return acquireLock(fqn, lockType, owner, timeout) != null;
}
+ public boolean lock(NodeSPI node, LockType lockType, Object owner, long timeout)
+ {
+ return acquireLock(node, lockType, owner, timeout) != null;
+ }
+
+
public boolean lockAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx)
{
return lockAndRecord(dataContainer.peek(fqn), lockType, ctx);
@@ -121,11 +128,12 @@
public void unlock(InvocationContext ctx)
{
List<NodeLock> locks = ctx.getTransactionEntry() != null ? ctx.getTransactionEntry().getLocks() : ctx.getInvocationLocksAcquired();
+ if (locks == null || locks.isEmpty()) return;
Object owner = getLockOwner(ctx);
// Copying out to an array is faster than creating an ArrayList and iterating,
// since list creation will just copy out to an array internally
- IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
+ NodeLock[] lockArray = locks.toArray(new NodeLock[locks.size()]);
for (int i = lockArray.length - 1; i >= 0; i--)
{
if (trace)
@@ -135,7 +143,7 @@
locks.clear();
}
- public void unlock(NodeLock lock, Object owner)
+ private void unlock(NodeLock lock, Object owner)
{
if (trace) log.trace("releasing lock for " + lock.getFqn() + " (" + lock + "), owner " + owner);
lock.release(owner);
@@ -146,6 +154,11 @@
unlock(dataContainer.peek(fqn).getLock(), owner);
}
+ public void unlock(NodeSPI node, Object owner)
+ {
+ unlock(node.getLock(), owner);
+ }
+
public boolean lockAll(NodeSPI node, LockType lockType, Object owner)
{
return lockAll(node, lockType, owner, lockAcquisitionTimeout, false);
@@ -168,6 +181,7 @@
*/
private List<NodeLock> lockAllNodes(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns)
{
+ if (node == null) return null;
List<NodeLock> locks = null;
try
{
16 years, 7 months
JBoss Cache SVN: r5888 - core/trunk/src/main/java/org/jboss/cache/interceptors.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-05-27 09:28:31 -0400 (Tue, 27 May 2008)
New Revision: 5888
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
Log:
only release locks in doAfterCall() if we are NOT running in a tx!
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-23 17:15:52 UTC (rev 5887)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-27 13:28:31 UTC (rev 5888)
@@ -295,7 +295,7 @@
@Override
public void doAfterCall(InvocationContext ctx, VisitableCommand command)
{
- lockManager.unlock(ctx);
+ if (ctx.getTransaction() == null) lockManager.unlock(ctx);
}
/**
16 years, 7 months
JBoss Cache SVN: r5887 - in core/trunk/src: main/java/org/jboss/cache/factories and 6 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-05-23 13:15:52 -0400 (Fri, 23 May 2008)
New Revision: 5887
Added:
core/trunk/src/main/java/org/jboss/cache/factories/LockManagerFactory.java
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
core/trunk/src/main/java/org/jboss/cache/lock/LockType.java
core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java
core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java
Removed:
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
Modified:
core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java
core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
core/trunk/src/main/java/org/jboss/cache/NodeSPI.java
core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/RegionManager.java
core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java
core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/lock/IdentityLock.java
core/trunk/src/main/java/org/jboss/cache/lock/LockUtil.java
core/trunk/src/main/java/org/jboss/cache/lock/NodeLock.java
core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferManager.java
core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java
core/trunk/src/test/java/org/jboss/cache/lock/AcquireAllTest.java
core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java
Log:
Refactored locks to use a LockManager rather than directly accessing locks from the NodeSPI. This is to allow for different locking systems, which are not associated with nodes - e.g., striped locks.
Modified: core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -9,6 +9,7 @@
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.factories.annotations.Stop;
import org.jboss.cache.invocation.NodeInvocationDelegate;
+import org.jboss.cache.lock.LockManager;
import org.jboss.cache.marshall.NodeData;
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.transaction.GlobalTransaction;
@@ -45,11 +46,12 @@
*/
private final Set<Fqn> internalFqns = new HashSet<Fqn>();
private NodeFactory nodeFactory;
+ private LockManager lockManager;
@Inject
- public void injectDependencies(Configuration configuration, NodeFactory nodeFactory)
+ public void injectDependencies(Configuration configuration, NodeFactory nodeFactory, LockManager lockManager)
{
- setDependencies(configuration, nodeFactory);
+ setDependencies(configuration, nodeFactory, lockManager);
// We need to create a root node even at this stage since certain components rely on this being available before
// start() is called.
@@ -58,10 +60,11 @@
createRootNode();
}
- public void setDependencies(Configuration configuration, NodeFactory nodeFactory)
+ public void setDependencies(Configuration configuration, NodeFactory nodeFactory, LockManager lockManager)
{
this.configuration = configuration;
this.nodeFactory = nodeFactory;
+ this.lockManager = lockManager;
}
@Start(priority = 12)
@@ -320,7 +323,7 @@
int num = 0;
if (n != null)
{
- if (n.getLock().isLocked())
+ if (lockManager.isLocked(n))
{
num++;
}
@@ -369,15 +372,7 @@
*/
public String printLockInfo()
{
- StringBuffer sb = new StringBuffer("\n");
- int indent = 0;
-
- for (Object n : root.getChildrenDirect())
- {
- ((NodeSPI) n).getLock().printLockInfo(sb, indent);
- sb.append("\n");
- }
- return sb.toString();
+ return lockManager.printLockInfo(root);
}
public int getNumberOfAttributes(Fqn fqn)
Modified: core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -39,12 +39,12 @@
// defaults to true.
private boolean originLocal = true;
private boolean txHasMods;
- private boolean cacheLoaderHasMods;
private boolean localRollbackOnly;
@Deprecated
private MethodCall methodCall;
@Deprecated
private VisitableCommand command;
+ List<NodeLock> invocationLocks;
// used to store cache peeks within the scope of a single context. Performing a cache peek can be a huge bottle neck.
// See JBCACHE-811
@@ -188,8 +188,6 @@
return originLocal;
}
- List<NodeLock> invocationLocks;
-
public List<NodeLock> getInvocationLocksAcquired()
{
return invocationLocks;
@@ -210,41 +208,6 @@
}
/**
- * for non-tx calls, release any locks acquired. These used to be in a separate Map<Thread, List<NodeLock>> called a lockTable,
- * but that has been dropped in facour of storing the invocation-specific locks in the invocation context. Cleaner to have it all
- * in one place, plus much more performant.
- */
- public void clearInvocationLocksAcquired()
- {
- if (isLockingSuppressed()) return;
- if (!isValidTransaction())
- { // no TX
- List<NodeLock> locks = getInvocationLocksAcquired();
- if (trace)
- log.trace("Attempting to release locks on current thread. Locks for the invocation is " + locks);
-
- if (locks != null && locks.size() > 0)
- {
- Thread currentThread = Thread.currentThread();
- try
- {
- // make sure we release locks in *reverse* order!
- for (int i = locks.size() - 1; i > -1; i--)
- {
- NodeLock nl = locks.get(i);
- if (trace) log.trace("releasing lock for " + nl.getFqn() + ": " + nl);
- nl.release(currentThread);
- }
- }
- finally
- {
- invocationLocks = null;
- }
- }
- }
- }
-
- /**
* @return true if options exist to suppress locking - false otherwise. Note that this is only used by the {@link org.jboss.cache.interceptors.PessimisticLockInterceptor}.
*/
public boolean isLockingSuppressed()
@@ -273,7 +236,6 @@
", optionOverrides=" + optionOverrides +
", originLocal=" + originLocal +
", txHasMods=" + txHasMods +
- ", cacheLoaderHasMods=" + cacheLoaderHasMods +
'}';
}
@@ -346,7 +308,6 @@
if (localRollbackOnly != that.localRollbackOnly) return false;
if (originLocal != that.originLocal) return false;
if (txHasMods != that.txHasMods) return false;
- if (cacheLoaderHasMods != that.cacheLoaderHasMods) return false;
if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
{
return false;
@@ -369,7 +330,6 @@
result = 29 * result + (optionOverrides != null ? optionOverrides.hashCode() : 0);
result = 29 * result + (originLocal ? 1 : 0);
result = 29 * result + (txHasMods ? 1 : 0);
- result = 29 * result + (cacheLoaderHasMods ? 1 : 0);
result = 29 * result + (localRollbackOnly ? 1 : 0);
return result;
}
Modified: core/trunk/src/main/java/org/jboss/cache/NodeSPI.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/NodeSPI.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/NodeSPI.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -108,7 +108,9 @@
* Returns a lock for this node.
*
* @return node lock
+ * @deprecated this will be removed in 3.0.0. Please use methods on the {@link org.jboss.cache.lock.LockManager} to lock and unlock nodes.
*/
+ @Deprecated
NodeLock getLock();
/**
Modified: core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -17,8 +17,8 @@
import org.jboss.cache.factories.annotations.Stop;
import org.jboss.cache.interceptors.InterceptorChain;
import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.lock.LockManager;
import org.jboss.cache.lock.LockUtil;
-import org.jboss.cache.lock.NodeLock;
import org.jboss.cache.lock.TimeoutException;
import org.jboss.cache.marshall.CommandAwareRpcDispatcher;
import org.jboss.cache.marshall.InactiveRegionAwareRpcDispatcher;
@@ -94,12 +94,13 @@
private boolean isUsingBuddyReplication;
private boolean isInLocalMode;
private ComponentRegistry componentRegistry;
+ private LockManager lockManager;
@Inject
private void setupDependencies(ChannelMessageListener messageListener, Configuration configuration, NotifierImpl notifier,
CacheSPI spi, Marshaller marshaller, TransactionTable txTable,
TransactionManager txManager, InvocationContextContainer container, InterceptorChain interceptorChain,
- ComponentRegistry componentRegistry)
+ ComponentRegistry componentRegistry, LockManager lockManager)
{
this.messageListener = messageListener;
this.configuration = configuration;
@@ -111,6 +112,7 @@
this.invocationContextContainer = container;
this.interceptorChain = interceptorChain;
this.componentRegistry = componentRegistry;
+ this.lockManager = lockManager;
}
// ------------ START: Lifecycle methods ------------
@@ -328,26 +330,20 @@
private void removeLocksForDeadMembers(NodeSPI node, List deadMembers)
{
Set<GlobalTransaction> deadOwners = new HashSet<GlobalTransaction>();
- NodeLock lock = node.getLock();
- Object owner = lock.getWriterOwner();
+ Object owner = lockManager.getWriteOwner(node);
- if (isLockOwnerDead(owner, deadMembers))
- {
- deadOwners.add((GlobalTransaction) owner);
- }
+ if (isLockOwnerDead(owner, deadMembers)) deadOwners.add((GlobalTransaction) owner);
- for (Object readOwner : lock.getReaderOwners())
+
+ for (Object readOwner : lockManager.getReadOwners(node))
{
- if (isLockOwnerDead(readOwner, deadMembers))
- {
- deadOwners.add((GlobalTransaction) readOwner);
- }
+ if (isLockOwnerDead(readOwner, deadMembers)) deadOwners.add((GlobalTransaction) readOwner);
}
for (GlobalTransaction deadOwner : deadOwners)
{
boolean localTx = deadOwner.getAddress().equals(getLocalAddress());
- boolean broken = LockUtil.breakTransactionLock(lock, deadOwner, localTx, txTable, txManager);
+ boolean broken = LockUtil.breakTransactionLock(node, lockManager, deadOwner, localTx, txTable, txManager);
if (broken && trace) log.trace("Broke lock for node " + node.getFqn() + " held by " + deadOwner);
}
Modified: core/trunk/src/main/java/org/jboss/cache/RegionManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionManager.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/RegionManager.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -18,7 +18,8 @@
import org.jboss.cache.factories.annotations.NonVolatile;
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.factories.annotations.Stop;
-import org.jboss.cache.lock.NodeLock;
+import org.jboss.cache.lock.LockManager;
+import static org.jboss.cache.lock.LockType.WRITE;
import org.jgroups.Address;
import java.util.ArrayList;
@@ -60,13 +61,15 @@
protected final Set<Fqn> activationChangeNodes = Collections.synchronizedSet(new HashSet<Fqn>());
protected Configuration configuration;
protected RPCManager rpcManager;
+ private LockManager lockManager;
@Inject
- void injectDependencies(CacheSPI cache, Configuration configuration, RPCManager rpcManager)
+ void injectDependencies(CacheSPI cache, Configuration configuration, RPCManager rpcManager, LockManager lockManager)
{
this.cache = cache;
this.rpcManager = rpcManager;
this.configuration = configuration;
+ this.lockManager = lockManager;
}
@Start
@@ -542,12 +545,10 @@
throw new CacheException("Region " + fqn + " is already being activated/deactivated");
}
- NodeSPI parent;
- NodeSPI subtreeRoot;
+ NodeSPI parent = null;
+ NodeSPI subtreeRoot = null;
boolean parentLocked = false;
boolean subtreeLocked = false;
- NodeLock parentLock = null;
- NodeLock subtreeLock = null;
try
{
@@ -586,18 +587,11 @@
// Acquire locks
Object owner = getOwnerForLock();
- subtreeLock = subtreeRoot.getLock();
- subtreeLock.acquireAll(owner, stateFetchTimeout, NodeLock.LockType.WRITE);
- subtreeLocked = true;
+ subtreeLocked = lockManager.lockAll(subtreeRoot, WRITE, owner, stateFetchTimeout);
// Lock the parent, as we're about to write to it
parent = subtreeRoot.getParent();
- if (parent != null)
- {
- parentLock = parent.getLock();
- parentLock.acquire(owner, stateFetchTimeout, NodeLock.LockType.WRITE);
- parentLocked = true;
- }
+ if (parent != null) parentLocked = lockManager.lock(parent.getFqn(), WRITE, owner, stateFetchTimeout);
// Remove the subtree
cache.evict(subtree, true);
@@ -607,21 +601,17 @@
if (parent != null)
{
log.debug("forcing release of locks in parent");
- parentLock.releaseAll();
+ lockManager.unlockAll(parent);
}
parentLocked = false;
log.debug("forcing release of all locks in subtree");
- subtreeLock.releaseAll();
+ lockManager.unlockAll(subtreeRoot);
subtreeLocked = false;
}
}
}
- catch (InterruptedException ie)
- {
- throw new CacheException("Interrupted while acquiring lock", ie);
- }
finally
{
// If we didn't succeed, undo the marshalling change
@@ -635,7 +625,7 @@
log.debug("forcing release of locks in parent");
try
{
- parentLock.releaseAll();
+ if (parent != null) lockManager.unlockAll(parent);
}
catch (Throwable t)
{
@@ -647,7 +637,7 @@
log.debug("forcing release of all locks in subtree");
try
{
- subtreeLock.releaseAll();
+ if (subtreeRoot != null) lockManager.unlockAll(subtreeRoot);
}
catch (Throwable t)
{
Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -172,6 +172,7 @@
s.add(RuntimeConfigAwareFactory.class);
s.add(TransactionManagerFactory.class);
s.add(ReplicationQueueFactory.class);
+ s.add(LockManagerFactory.class);
return s;
}
Modified: core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -7,7 +7,6 @@
import org.jboss.cache.invocation.CacheInvocationDelegate;
import org.jboss.cache.invocation.InvocationContextContainer;
import org.jboss.cache.loader.CacheLoaderManager;
-import org.jboss.cache.lock.LockManager;
import org.jboss.cache.lock.LockStrategyFactory;
import org.jboss.cache.marshall.Marshaller;
import org.jboss.cache.marshall.VersionAwareMarshaller;
@@ -25,7 +24,7 @@
@DefaultFactoryFor(classes = {StateTransferManager.class, RegionManager.class, NotifierImpl.class,
ChannelMessageListener.class, CacheLoaderManager.class, Marshaller.class,
InvocationContextContainer.class, CacheInvocationDelegate.class,
- TransactionTable.class, DataContainerImpl.class, CommandsFactory.class, LockManager.class,
+ TransactionTable.class, DataContainerImpl.class, CommandsFactory.class,
LockStrategyFactory.class})
public class EmptyConstructorFactory extends ComponentFactory
{
Added: core/trunk/src/main/java/org/jboss/cache/factories/LockManagerFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/LockManagerFactory.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/LockManagerFactory.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -0,0 +1,30 @@
+package org.jboss.cache.factories;
+
+import org.jboss.cache.factories.annotations.DefaultFactoryFor;
+import org.jboss.cache.lock.LockManager;
+import org.jboss.cache.lock.NodeBasedLockManager;
+import org.jboss.cache.lock.PessimisticNodeBasedLockManager;
+
+/**
+ * Creates lock managers
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.2.0
+ */
+@DefaultFactoryFor(classes = LockManager.class)
+public class LockManagerFactory extends EmptyConstructorFactory
+{
+ @Override
+ @SuppressWarnings({"unchecked", "deprecation"})
+ protected <T> T construct(Class<T> componentType)
+ {
+ if (configuration.isNodeLockingOptimistic())
+ {
+ return (T) super.construct(NodeBasedLockManager.class);
+ }
+ else
+ {
+ return (T) super.construct(PessimisticNodeBasedLockManager.class);
+ }
+ }
+}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -12,11 +12,11 @@
import org.jboss.cache.commands.read.GetKeysCommand;
import org.jboss.cache.commands.read.GetNodeCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
+import org.jboss.cache.commands.write.ClearDataCommand;
import org.jboss.cache.commands.write.MoveCommand;
import org.jboss.cache.commands.write.PutDataMapCommand;
import org.jboss.cache.commands.write.PutForExternalReadCommand;
import org.jboss.cache.commands.write.PutKeyValueCommand;
-import org.jboss.cache.commands.write.ClearDataCommand;
import org.jboss.cache.commands.write.RemoveKeyCommand;
import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.config.Configuration;
@@ -27,7 +27,7 @@
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.loader.CacheLoaderManager;
import org.jboss.cache.lock.LockManager;
-import org.jboss.cache.lock.NodeLock;
+import org.jboss.cache.lock.LockType;
import org.jboss.cache.notifications.NotifierImpl;
import org.jboss.cache.transaction.TransactionEntry;
import org.jboss.cache.transaction.TransactionTable;
@@ -270,7 +270,7 @@
// - Manik Surtani (21 March 2006)
if (acquireLock)
{
- lock(fqn, NodeLock.LockType.WRITE, false, ctx);// non-recursive for now
+ lock(fqn, LockType.WRITE, false, ctx);// non-recursive for now
}
// if (!initNode && !wasRemovedInTx(fqn, ctx.getGlobalTransaction()))
@@ -358,7 +358,7 @@
loadChildren(child.getFqn(), child, true, isMove, ctxt);
}
}
- lock(fqn, recursive ? NodeLock.LockType.WRITE : NodeLock.LockType.READ, true, ctxt);// recursive=true: lock entire subtree
+ lock(fqn, recursive ? LockType.WRITE : LockType.READ, true, ctxt);// recursive=true: lock entire subtree
node.setChildrenLoaded(true);
}
@@ -427,15 +427,12 @@
return retval;
}
- protected void lock(Fqn fqn, NodeLock.LockType lockType, boolean recursive, InvocationContext ctx) throws Throwable
+ protected void lock(Fqn fqn, LockType lockType, boolean recursive, InvocationContext ctx) throws Throwable
{
if (configuration.isNodeLockingOptimistic()) return;
- lockManager.acquireLocksWithTimeout(ctx, fqn, lockType, false, false, false, false, null, false);
- if (recursive)
- {
- NodeSPI node = dataContainer.peek(fqn, false, false);
- lockManager.acquireLocksOnChildren(node, lockType, ctx);
- }
+
+ lockManager.lock(fqn, lockType, ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread());
+ if (recursive) lockManager.lockAllAndRecord(fqn, lockType, ctx);
}
/**
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticInterceptor.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -13,6 +13,8 @@
import org.jboss.cache.NodeSPI;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.lock.LockManager;
+import static org.jboss.cache.lock.LockType.READ;
import org.jboss.cache.lock.TimeoutException;
import org.jboss.cache.optimistic.TransactionWorkspace;
import org.jboss.cache.optimistic.WorkspaceNode;
@@ -33,12 +35,14 @@
{
protected TransactionManager txManager;
protected TransactionTable txTable;
+ protected LockManager lockManager;
@Inject
- private void injectDependencies(TransactionManager txManager, TransactionTable txTable)
+ private void injectDependencies(TransactionManager txManager, TransactionTable txTable, LockManager lockManager)
{
this.txManager = txManager;
this.txTable = txTable;
+ this.lockManager = lockManager;
}
protected TransactionWorkspace getTransactionWorkspace(InvocationContext ctx) throws CacheException
@@ -92,7 +96,9 @@
* Undeletes a node that already exists in the workspace, by setting appropriate flags and re-adding to parent's child map.
*
* @param nodeToUndelete WorkspaceNode to undelete
+ * @param parent parent of node to undelete
*/
+ @SuppressWarnings("unchecked")
protected void undeleteWorkspaceNode(WorkspaceNode nodeToUndelete, WorkspaceNode parent)
{
nodeToUndelete.markAsDeleted(false);
@@ -102,21 +108,17 @@
nodeToUndelete.markAsResurrected(true);
}
+ @SuppressWarnings("unchecked")
protected WorkspaceNode lockAndCreateWorkspaceNode(NodeFactory nodeFactory, NodeSPI node, TransactionWorkspace workspace, GlobalTransaction gtx, long timeout)
{
- boolean locked = false;
- try
- {
- locked = node.getLock().acquireReadLock(gtx, timeout);
- }
- catch (InterruptedException e)
- {
- // do nothing
- }
+ boolean locked = lockManager.lock(node.getFqn(), READ, gtx, timeout);
+
if (!locked)
throw new TimeoutException("Unable to lock node " + node.getFqn() + " after timeout " + timeout + " for copying into workspace");
+
WorkspaceNode wn = nodeFactory.createWorkspaceNode(node, workspace);
- node.getLock().release(gtx);
+
+ lockManager.unlock(node.getFqn(), gtx);
return wn;
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -13,11 +13,9 @@
import org.jboss.cache.commands.tx.CommitCommand;
import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
-import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.lock.LockManager;
-import static org.jboss.cache.lock.NodeLock.LockType.READ;
-import static org.jboss.cache.lock.NodeLock.LockType.WRITE;
+import static org.jboss.cache.lock.LockType.READ;
+import static org.jboss.cache.lock.LockType.WRITE;
import org.jboss.cache.optimistic.TransactionWorkspace;
import org.jboss.cache.optimistic.WorkspaceNode;
import org.jboss.cache.transaction.GlobalTransaction;
@@ -33,14 +31,7 @@
public class OptimisticLockingInterceptor extends OptimisticInterceptor
{
private long lockAcquisitionTimeout;
- private LockManager lockManager;
- @Inject
- private void injectLockManager(LockManager lockManager)
- {
- this.lockManager = lockManager;
- }
-
@Start
private void init()
{
@@ -54,18 +45,11 @@
{
//try and acquire the locks - before passing on
GlobalTransaction gtx = getGlobalTransaction(ctx);
- long timeout = lockAcquisitionTimeout;
- if (ctx.getOptionOverrides() != null
- && ctx.getOptionOverrides().getLockAcquisitionTimeout() >= 0)
- {
- timeout = ctx.getOptionOverrides().getLockAcquisitionTimeout();
- }
boolean succeeded = false;
try
{
TransactionWorkspace<?, ?> workspace = getTransactionWorkspace(ctx);
- TransactionEntry te = ctx.getTransactionEntry();
if (log.isDebugEnabled()) log.debug("Locking nodes in transaction workspace for GlobalTransaction " + gtx);
for (WorkspaceNode workspaceNode : workspace.getNodes().values())
@@ -74,11 +58,10 @@
boolean isWriteLockNeeded = workspaceNode.isDirty() || (workspaceNode.isChildrenModified() && (configuration.isLockParentForChildInsertRemove() || node.isLockForChildInsertRemove()));
- boolean acquired = node.getLock().acquire(gtx, timeout, isWriteLockNeeded ? WRITE : READ);
+ boolean acquired = lockManager.lockAndRecord(node, isWriteLockNeeded ? WRITE : READ, ctx);
if (acquired)
{
if (trace) log.trace("Acquired lock on node " + node.getFqn());
- te.addLock(node.getLock());
}
else
{
@@ -101,7 +84,7 @@
}
finally
{
- if (!succeeded) unlock(ctx, gtx);
+ if (!succeeded) unlock(ctx);
}
}
@@ -128,7 +111,7 @@
}
finally
{
- unlock(ctx, getGlobalTransaction(ctx));
+ unlock(ctx);
}
return retval;
}
@@ -138,14 +121,14 @@
*
* @param ctx Invocation Context
*/
- private void unlock(InvocationContext ctx, GlobalTransaction gtx)
+ private void unlock(InvocationContext ctx)
{
try
{
TransactionEntry entry = ctx.getTransactionEntry();
if (entry != null)
{
- lockManager.releaseLocks(entry.getLocks(), ctx.getGlobalTransaction());
+ lockManager.unlock(ctx);
}
}
catch (Exception e)
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -31,7 +31,9 @@
import org.jboss.cache.interceptors.base.PostProcessingCommandInterceptor;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.lock.LockManager;
-import org.jboss.cache.lock.NodeLock;
+import static org.jboss.cache.lock.LockType.READ;
+import static org.jboss.cache.lock.LockType.WRITE;
+import org.jboss.cache.lock.PessimisticNodeBasedLockManager;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionEntry;
@@ -58,13 +60,13 @@
public class PessimisticLockInterceptor extends PostProcessingCommandInterceptor
{
private DataContainerImpl dataContainer;
- private LockManager lockManager;
+ private PessimisticNodeBasedLockManager lockManager;
@Inject
public void injectDependencies(DataContainerImpl dataContainer, LockManager lockManager)
{
this.dataContainer = dataContainer;
- this.lockManager = lockManager;
+ this.lockManager = (PessimisticNodeBasedLockManager) lockManager;
}
@Override
@@ -105,7 +107,7 @@
}
else
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, true,
+ lockManager.lockPessimistically(ctx, command.getFqn(), WRITE, true,
zeroAcquisitionTimeout, false, true, null, false);
}
return invokeNextInterceptor(ctx, command);
@@ -120,7 +122,7 @@
// commit propagated up from the tx interceptor
commit(ctx.getTransactionEntry(), ctx.getGlobalTransaction());
Object retVal = invokeNextInterceptor(ctx, command);
- lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(), ctx.getGlobalTransaction());
+ lockManager.unlock(ctx);
return retVal;
}
@@ -130,7 +132,7 @@
commit(ctx.getTransactionEntry(), command.getGlobalTransaction());
if (trace) log.trace("bypassed locking as method commit() doesn't require locking");
Object retVal = invokeNextInterceptor(ctx, command);
- lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(), ctx.getGlobalTransaction());
+ lockManager.unlock(ctx);
return retVal;
}
@@ -160,7 +162,7 @@
log.trace("bypassed locking as method rollback() doesn't require locking");
}
Object retVal = invokeNextInterceptor(ctx, command);
- lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(), ctx.getGlobalTransaction());
+ lockManager.unlock(ctx);
return retVal;
}
@@ -168,31 +170,29 @@
protected Object handleMoveCommand(InvocationContext ctx, MoveCommand command) throws Throwable
{
if (ctx.isLockingSuppressed()) return invokeNextInterceptor(ctx, command);
+
// this call will ensure the node gets a WL and it's current parent gets RL.
if (trace) log.trace("Attempting to get WL on node to be moved [" + command.getFqn() + "]");
if (command.getFqn() != null && !(configuration.getIsolationLevel() == IsolationLevel.NONE))
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, false, true, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), WRITE, false, false, true, false, null, false);
if (ctx.getGlobalTransaction() != null)
{
ctx.getTransactionEntry().addRemovedNode(command.getFqn());
}
- lockManager.acquireLocksOnChildren(dataContainer.peek(command.getFqn(), true, false), NodeLock.LockType.WRITE, ctx);
+ lockManager.lockAllAndRecord(dataContainer.peek(command.getFqn(), true, false), WRITE, ctx);
}
if (command.getTo() != null && !(configuration.getIsolationLevel() == IsolationLevel.NONE))
{
//now for an RL for the new parent.
if (trace) log.trace("Attempting to get RL on new parent [" + command.getTo() + "]");
- lockManager.acquireLocksWithTimeout(ctx, command.getTo(), NodeLock.LockType.READ, false, false, false, false, null, false);
- lockManager.acquireLocksOnChildren(dataContainer.peek(command.getTo(), true, false), NodeLock.LockType.READ, ctx);
+ lockManager.lockPessimistically(ctx, command.getTo(), READ, false, false, false, false, null, false);
+ lockManager.lockAllAndRecord(dataContainer.peek(command.getTo(), true, false), READ, ctx);
}
Object retValue = invokeNextInterceptor(ctx, command);
// do a REAL remove here.
NodeSPI n = dataContainer.peek(command.getFqn(), true, false);
- if (n != null)
- {
- n.getLock().releaseAll(Thread.currentThread());
- }
+ if (n != null) lockManager.unlockAll(n, Thread.currentThread());
return retValue;
}
@@ -204,7 +204,7 @@
List<NodeSPI> createdNodes = new LinkedList<NodeSPI>();
// we need to mark new nodes created as deleted since they are only created to form a path to the node being removed, to
// create a lock.
- boolean created = lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, true, false, true, true, createdNodes, true);
+ boolean created = lockManager.lockPessimistically(ctx, command.getFqn(), WRITE, true, false, true, true, createdNodes, true);
TransactionEntry entry = null;
if (ctx.getGlobalTransaction() != null)
{
@@ -216,8 +216,9 @@
nodeSPI.markAsDeleted(true);
}
}
- lockManager.acquireLocksOnChildren(dataContainer.peek(command.getFqn(), false, false), NodeLock.LockType.WRITE, ctx, entry, true);
+ lockManager.lockAllForRemoval(dataContainer.peek(command.getFqn(), false, false), ctx, entry);
+
if (!createdNodes.isEmpty())
{
if (trace) log.trace("There were new nodes created, skipping notification on delete");
@@ -236,10 +237,7 @@
//TODO: 2.2.0: end of the logic that needs to be moved
NodeSPI n = dataContainer.peek(command.getFqn(), true, false);
- if (n != null)
- {
- n.getLock().releaseAll(Thread.currentThread());
- }
+ if (n != null) lockManager.unlockAll(n, Thread.currentThread());
}
// if this is a delete op and we had to create the node, return a FALSE as nothing *really* was deleted!
return created ? false : retVal;
@@ -248,56 +246,56 @@
@Override
protected Object handleRemoveKeyCommand(InvocationContext ctx, RemoveKeyCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, false, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), WRITE, false, false, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
protected Object handleRemoveDataCommand(InvocationContext ctx, ClearDataCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, false, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), WRITE, false, false, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
protected Object handleEvictFqnCommand(InvocationContext ctx, EvictCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, true, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), WRITE, false, true, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
protected Object handleGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.READ, false, false, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), READ, false, false, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
protected Object handleGetNodeCommand(InvocationContext ctx, GetNodeCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.READ, false, false, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), READ, false, false, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
protected Object handleGetKeysCommand(InvocationContext ctx, GetKeysCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.READ, false, false, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), READ, false, false, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
protected Object handleGetChildrenNamesCommand(InvocationContext ctx, GetChildrenNamesCommand command) throws Throwable
{
- lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.READ, false, false, false, false, null, false);
+ lockManager.lockPessimistically(ctx, command.getFqn(), READ, false, false, false, false, null, false);
return invokeNextInterceptor(ctx, command);
}
@Override
public void doAfterCall(InvocationContext ctx, VisitableCommand command)
{
- ctx.clearInvocationLocksAcquired();
+ lockManager.unlock(ctx);
}
/**
@@ -317,4 +315,5 @@
dataContainer.removeFromDataStructure(fqn, false);
}
}
+
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -600,10 +600,7 @@
protected void cleanupStaleLocks(InvocationContext ctx) throws Throwable
{
TransactionEntry entry = ctx.getTransactionEntry();
- if (entry != null)
- {
- lockManager.releaseLocks(entry.getLocks(), ctx.getGlobalTransaction());
- }
+ if (entry != null) lockManager.unlock(ctx);
}
/**
Modified: core/trunk/src/main/java/org/jboss/cache/lock/IdentityLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/IdentityLock.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/lock/IdentityLock.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -62,6 +62,7 @@
* @author Ben Wang July 2003
* @version $Revision$
*/
+@SuppressWarnings("deprecation")
public class IdentityLock implements NodeLock
{
@@ -469,15 +470,15 @@
}
}
- public boolean acquire(Object caller, long timeout, NodeLock.LockType lock_type) throws LockingException, TimeoutException, InterruptedException
+ public boolean acquire(Object caller, long timeout, LockType lock_type) throws LockingException, TimeoutException, InterruptedException
{
try
{
- if (lock_type == NodeLock.LockType.NONE)
+ if (lock_type == LockType.NONE)
{
return true;
}
- else if (lock_type == NodeLock.LockType.READ)
+ else if (lock_type == LockType.READ)
{
return acquireReadLock(caller, timeout);
}
Deleted: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -1,343 +0,0 @@
-package org.jboss.cache.lock;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.DataContainerImpl;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.InvocationContext;
-import org.jboss.cache.NodeSPI;
-import org.jboss.cache.commands.write.PutDataMapCommand;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.factories.CommandsFactory;
-import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.transaction.GlobalTransaction;
-import org.jboss.cache.transaction.TransactionEntry;
-import org.jboss.cache.transaction.TransactionTable;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Mircea.Markus(a)jboss.com
- * @since 2.2
- */
-public class LockManager
-{
- private static final Log log = LogFactory.getLog(LockManager.class);
- private static final boolean trace = log.isTraceEnabled();
-
- private Configuration configuration;
- private long lockAcquisitionTimeout;
- private DataContainerImpl dataContainer;
- private NodeSPI rootNode;
- private TransactionTable txTable;
- private CommandsFactory commandsFactory;
-
- @Inject
- public void inject(Configuration configuration, DataContainerImpl dataContainer, TransactionTable txTable,
- CommandsFactory commandsFactory)
- {
- this.configuration = configuration;
- this.dataContainer = dataContainer;
- this.txTable = txTable;
- this.commandsFactory = commandsFactory;
- }
-
- @Start
- public void setRootNode()
- {
- this.lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
- rootNode = dataContainer.getRoot();
- }
-
-
- public boolean acquireLocksWithTimeout(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType,
- boolean createIfNotExists, boolean zeroLockTimeout,
- boolean acquireLockOnParent, boolean reverseRemoveCheck, List<NodeSPI> createdNodes, boolean skipNotification)
- throws InterruptedException
- {
- if (fqn == null || configuration.getIsolationLevel() == IsolationLevel.NONE || ctx.isLockingSuppressed())
- return false;
-
- boolean created;
- long timeout = zeroLockTimeout ? 0 : ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout);
- // make sure we can bail out of this loop
- long cutoffTime = System.currentTimeMillis() + timeout;
- boolean firstTry = true;
- do
- {
- // this is an additional check to make sure we don't try for too long.
- if (!firstTry && System.currentTimeMillis() > cutoffTime)
- {
- throw new TimeoutException("Unable to acquire lock on Fqn " + fqn + " after " + timeout + " millis");
- }
- created = lock(ctx, fqn, lockType, createIfNotExists, timeout, acquireLockOnParent, reverseRemoveCheck, createdNodes, skipNotification);
- firstTry = false;
- }
- while (createIfNotExists && (dataContainer.peek(fqn, false, false) == null));// keep trying until we have the lock (fixes concurrent remove())
- return created;
- }
-
-
- /**
- * Acquires locks on the node and on its parrents. Read locks are acquired for exsiting ancestors, with two exceptions:
- * 1) createIfNotExists is true. If an ancestor is created on the fly, then an WL is acquired by default
- * 2) acquireWriteLockOnParent is true. If so AND {@link org.jboss.cache.Node#isLockForChildInsertRemove()} then a read
- * lock will be aquired for the parent of the node.
- *
- * @param createIfNotExists if true, then missing nodes will be cretaed on the fly. If false, method returns if we
- * reach a node that does not exists
- * @param reverseRemoveCheck see {@link #manageReverseRemove(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.NodeSPI, boolean, java.util.List)}
- * @param createdNodes a list to which any nodes created can register their Fqns so that calling code is aware of which nodes have been newly created.
- * @param skipNotification
- */
- private boolean lock(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType, boolean createIfNotExists, long timeout,
- boolean acquireWriteLockOnParent, boolean reverseRemoveCheck, List<NodeSPI> createdNodes, boolean skipNotification)
- throws TimeoutException, LockingException, InterruptedException
- {
- Thread currentThread = Thread.currentThread();
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- boolean created = false;
- // if the tx associated with the current thread is rolling back, barf! JBCACHE-923
- if (gtx != null) TransactionTable.assertTransactionValid(ctx);
-
- Object owner = (gtx != null) ? gtx : currentThread;
- NodeSPI currentNode;
- if (trace) log.trace("Attempting to lock node " + fqn + " for owner " + owner);
- long expiryTime = System.currentTimeMillis() + timeout;
- currentNode = rootNode;
- NodeSPI parent = null;
- Object childName = null;
- int currentIndex = -1;
- int targetFqnSize = fqn.size();
-
- do
- {
- if (currentNode == null)
- {
- if (createIfNotExists)
- {
- // if the new node is to be marked as deleted, do not notify!
- currentNode = parent.addChildDirect(childName, !skipNotification);
- created = true;
- if (trace) log.trace("Child node was null, so created child node " + childName);
- if (createdNodes != null) createdNodes.add(currentNode);
- }
- else
- {
- if (trace)
- log.trace("failed to find or create child " + childName + " of node " + parent);
- return false;
- }
- }
- else
- {
- if (!currentNode.isValid() && createIfNotExists) currentNode.setValid(true, false);
- }
-
- NodeLock.LockType lockTypeRequired = NodeLock.LockType.READ;
- if (created || writeLockNeeded(ctx, lockType, currentIndex, acquireWriteLockOnParent, createIfNotExists, fqn, currentNode))
- {
- lockTypeRequired = NodeLock.LockType.WRITE;
- }
-
- Fqn currentNodeFqn = currentNode.getFqn();
- // actually acquire the lock we need. This method blocks.
- acquireNodeLock(ctx, currentNode, owner, gtx, lockTypeRequired, timeout);
-
- manageReverseRemove(ctx, currentNode, reverseRemoveCheck, createdNodes);
- // make sure the lock we acquired isn't on a deleted node/is an orphan!!
- // look into invalidated nodes as well
- NodeSPI repeek = dataContainer.peek(currentNodeFqn, true, true);
- if (currentNode != repeek)
- {
- if (trace)
- log.trace("Was waiting for and obtained a lock on a node that doesn't exist anymore! Attempting lock acquisition again.");
- // we have an orphan!! Lose the unnecessary lock and re-acquire the lock (and potentially recreate the node).
- // check if the parent exists!!
- // look into invalidated nodes as well
- currentNode.getLock().releaseAll(owner);
- if (parent == null || dataContainer.peek(parent.getFqn(), true, true) == null)
- {
- // crap!
- if (trace)
- log.trace("Parent has been deleted again. Go through the lock method all over again.");
- currentNode = rootNode;
- currentIndex = -1;
- parent = null;
- }
- else
- {
- currentNode = parent;
- currentIndex--;
- parent = null;
- if (System.currentTimeMillis() > expiryTime)
- {
- throw new TimeoutException("Unable to acquire lock on child node " + Fqn.fromRelativeElements(currentNode.getFqn(), childName) + " after " + timeout + " millis.");
- }
- if (trace) log.trace("Moving one level up, current node is :" + currentNode);
- }
- }
- else
- {
- // we have succeeded in acquiring this lock. Increment the current index since we have gained one level of depth in the tree.
- currentIndex++;
-
- // now test if this is the final level and if we can quit the loop:
- //if (currentNodeFqn.equals(fqn))//we've just processed the last child
- if (currentIndex == targetFqnSize)
- {
- break;
- }
- if (!fqn.isChildOrEquals(currentNode.getFqn())) // Does this ever happen? Perhaps with a move(), I suppose? - MS
- {
- String message = new StringBuffer("currentNode instance changed the FQN(").append(currentNode.getFqn())
- .append(") and do not match the FQN on which we want to acquire lock(").append(fqn).append(")").toString();
- log.trace(message);
- throw new LockingException(message);
- }
- parent = currentNode;
-
- childName = fqn.get(currentIndex);
- currentNode = currentNode.getChildDirect(childName);
- }
- }
- while (true);
- return created;
- }
-
- /**
- * Used by lock()
- * Determins whter an arbitrary node from the supplied fqn needs an write lock.
- */
- private boolean writeLockNeeded(InvocationContext ctx, NodeLock.LockType lockType, int currentNodeIndex, boolean acquireWriteLockOnParent, boolean createIfNotExists, Fqn targetFqn, NodeSPI currentNode)
- {
- int treeNodeSize = targetFqn.size();
- // write lock forced!!
- boolean isTargetNode = currentNodeIndex == (treeNodeSize - 1);
- if (isTargetNode && ctx.getOptionOverrides().isForceWriteLock()) return true;
- //this can be injected, from the caller as a param named wlParent
- if (currentNode.isLockForChildInsertRemove())
- {
- if (acquireWriteLockOnParent && currentNodeIndex == treeNodeSize - 2)
- {
- return true;// we're doing a remove and we've reached the PARENT node of the target to be removed.
- }
- if (!isTargetNode && dataContainer.peek(targetFqn.getAncestor(currentNodeIndex + 2), false, false) == null)
- {
- return createIfNotExists;// we're at a node in the tree, not yet at the target node, and we need to create the next node. So we need a WL here.
- }
- }
- return lockType == NodeLock.LockType.WRITE && isTargetNode;//write lock explicitly requested and this is the target to be written to.
- }
-
- private void acquireNodeLock(InvocationContext ctx, NodeSPI node, Object owner, GlobalTransaction gtx, NodeLock.LockType lockType, long lockTimeout) throws LockingException, TimeoutException, InterruptedException
- {
- NodeLock lock = node.getLock();
- boolean acquired = lock.acquire(owner, lockTimeout, lockType);
- if (acquired)
- {
- // Record the lock for release on method return or tx commit/rollback
- if (gtx != null)
- {
- ctx.getTransactionEntry().addLock(lock);
- }
- else
- {
- ctx.addInvocationLockAcquired(lock);
- }
- }
- }
-
- /**
- * Test if this node needs to be 'undeleted'
- * reverse the "remove" if the node has been previously removed in the same tx, if this operation is a put()
- */
- public void manageReverseRemove(InvocationContext ctx, NodeSPI childNode, boolean reverseRemoveCheck, List createdNodes)
- {
- if (ctx.getGlobalTransaction() != null) //if no tx then reverse remove does not make sense
- {
- Fqn fqn = childNode.getFqn();
- TransactionEntry entry = ctx.getTransactionEntry();
- boolean needToReverseRemove = reverseRemoveCheck && childNode.isDeleted() && isNodeRemovedInCurrentTransaction(entry, fqn);
- if (!needToReverseRemove) return;
- childNode.markAsDeleted(false);
- //if we'll rollback the tx data should be added to the node again
- Map oldData = new HashMap(childNode.getDataDirect());
- PutDataMapCommand command = commandsFactory.buildPutDataMapCommand(ctx.getGlobalTransaction(), fqn, oldData);
- // txTable.get(gtx).addUndoOperation(command); --- now need to make sure this is added to the normal mods list instead
- entry.addModification(command);
- //we're prepared for rollback, now reset the node
- childNode.clearDataDirect();
- if (createdNodes != null)
- {
- createdNodes.add(childNode);
- }
- }
- }
-
- private boolean isNodeRemovedInCurrentTransaction(TransactionEntry entry, Fqn fqn)
- {
- return entry != null && entry.getRemovedNodes().contains(fqn);
- }
-
- public void acquireLocksOnChildren(NodeSPI parentNode, NodeLock.LockType lockType, InvocationContext ctx) throws InterruptedException
- {
- acquireLocksOnChildren(parentNode, lockType, ctx, null, false);
- }
-
- /**
- * Acquires nodes on the children of this node. nodes on the node itself are not aquired.
- * If the supplied parent node is null the method returns(no op).
- */
- public void acquireLocksOnChildren(NodeSPI parentNode, NodeLock.LockType lockType, InvocationContext ctx, TransactionEntry entry, boolean addChildrenToDeletedList)
- throws InterruptedException
- {
- if (parentNode == null)
- {
- return;
- }
- long timeout = ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout);
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- Object owner = (gtx != null) ? gtx : Thread.currentThread();
-
- Set<NodeLock> acquiredLocks = parentNode.getLock().acquireAll(owner, timeout, lockType);
- if (acquiredLocks.size() > 0)
- {
- if (gtx != null)
- {
- ctx.getTransactionEntry().addLocks(acquiredLocks);
- if (addChildrenToDeletedList)
- {
- for (NodeLock l : acquiredLocks)
- {
- entry.addRemovedNode(l.getFqn());
- }
- }
- }
- else
- {
- ctx.addInvocationLocksAcquired(acquiredLocks);
- }
- }
- }
-
- /**
- * Releases all locks held by the owner, in reverse order of creation.
- */
- public void releaseLocks(List<NodeLock> locks, Object owner)
- {
- // Copying out to an array is faster than creating an ArrayList and iterating,
- // since list creation will just copy out to an array internally
- IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
- for (int i = lockArray.length - 1; i >= 0; i--)
- {
- if (trace) log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + ")");
- lockArray[i].release(owner);
- }
- locks.clear();
- }
-}
Added: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -0,0 +1,270 @@
+package org.jboss.cache.lock;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.NodeSPI;
+
+import java.util.Collection;
+
+/**
+ * An interface to deal with all aspects of acquiring and releasing locks for nodes in the cache.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.2.0
+ */
+public interface LockManager
+{
+ /**
+ * Determines the owner to be used when obtaining locks, given an invocation context. This is typically a {@link org.jboss.cache.transaction.GlobalTransaction} if one
+ * is present in the context, or {@link Thread#currentThread()} if one is not present.
+ *
+ * @param ctx invocation context
+ * @return owner to be used for acquiring locks.
+ */
+ Object getLockOwner(InvocationContext ctx);
+
+ /**
+ * Acquires a lock of type lockType, for a given owner, on a specific Node in the cache, denoted by fqn. This
+ * method will try for {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} milliseconds and give up if it is unable to acquire the required lock.
+ *
+ * @param fqn Fqn to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire the lock for
+ * @return true if the lock was acquired, false otherwise.
+ */
+ boolean lock(Fqn fqn, LockType lockType, Object owner);
+
+ /**
+ * Acquires a lock of type lockType, for a given owner, on a specific Node in the cache, denoted by fqn. This
+ * method will try for timeout milliseconds and give up if it is unable to acquire the required lock.
+ *
+ * @param fqn Fqn to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire the lock for
+ * @param timeout maximum length of time to wait for (in millis)
+ * @return true if the lock was acquired, false otherwise.
+ */
+ boolean lock(Fqn fqn, LockType lockType, Object owner, long timeout);
+
+ /**
+ * Acquires a lock of type lockType, on a specific Node in the cache, denoted by fqn. This
+ * method will try for a period of time and give up if it is unable to acquire the required lock. The period of time
+ * is specified in {@link org.jboss.cache.config.Option#getLockAcquisitionTimeout()} and, if this is unset, the default timeout
+ * set in {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} is used.
+ * <p/>
+ * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
+ * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * <p/>
+ * The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
+ * <p/>
+ *
+ * @param fqn Fqn to lock
+ * @param lockType type of lock to acquire
+ * @param ctx invocation context associated with this invocation
+ * @return true if the lock was acquired, false otherwise.
+ */
+ boolean lockAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx);
+
+ /**
+ * Acquires a lock of type lockType, on a specific Node in the cache, denoted by fqn. This
+ * method will try for a period of time and give up if it is unable to acquire the required lock. The period of time
+ * is specified in {@link org.jboss.cache.config.Option#getLockAcquisitionTimeout()} and, if this is unset, the default timeout
+ * set in {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} is used.
+ * <p/>
+ * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
+ * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * <p/>
+ * The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
+ * <p/>
+ *
+ * @param node Fqn to lock
+ * @param lockType type of lock to acquire
+ * @param ctx invocation context associated with this invocation
+ * @return true if the lock was acquired, false otherwise.
+ */
+ boolean lockAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx);
+
+
+ /**
+ * Releases the lock passed in, held by the specified owner
+ *
+ * @param lock NodeLock to unlock
+ * @param owner lock owner
+ */
+ void unlock(NodeLock lock, Object owner);
+
+ /**
+ * Releases the lock passed in, held by the specified owner
+ *
+ * @param fqn Fqn of the node to unlock
+ * @param owner lock owner
+ */
+ void unlock(Fqn fqn, Object owner);
+
+ /**
+ * Releases locks present in an invocation context and transaction entry, if one is available.
+ * <p/>
+ * Locks are released in reverse order of which they are acquired and registered.
+ * <p/>
+ * Lock owner is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}
+ * <p/>
+ *
+ * @param ctx invocation context to inspect
+ */
+ void unlock(InvocationContext ctx);
+
+
+ /**
+ * Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
+ * acquired, all locks are released and the method returns false.
+ * <p/>
+ * This method will try for {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} milliseconds and give up if it is unable to acquire the required lock.
+ * <p/>
+ *
+ * @param node Node to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire the lock for
+ * @return true if the lock was acquired, false otherwise.
+ */
+ boolean lockAll(NodeSPI node, LockType lockType, Object owner);
+
+ /**
+ * Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
+ * acquired, all locks are released and the method returns false. Internal Fqns are included as well.
+ *
+ * @param node Node to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire the lock for
+ * @param timeout maximum length of time to wait for (in millis)
+ * @return true if all locks were acquired, false otherwise.
+ */
+ boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout);
+
+ /**
+ * Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
+ * acquired, all locks are released and the method returns false.
+ *
+ * @param node Node to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire the lock for
+ * @param timeout maximum length of time to wait for (in millis)
+ * @param excludeInternalFqns if true, any Fqns that are internal are excluded.
+ * @return true if all locks were acquired, false otherwise.
+ */
+ boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns);
+
+ /**
+ * Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
+ * acquired, all locks are released and the method returns false.
+ * <p/>
+ * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
+ * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * <p/>
+ * The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
+ * <p/>
+ *
+ * @param node Node to lock
+ * @param lockType type of lock to acquire
+ * @param ctx invocation context associated with this invocation
+ * @return true if all locks were acquired, false otherwise.
+ */
+ boolean lockAllAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx);
+
+ /**
+ * Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
+ * acquired, all locks are released and the method returns false.
+ * <p/>
+ * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
+ * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * <p/>
+ * The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
+ * <p/>
+ *
+ * @param fqn Node to lock
+ * @param lockType type of lock to acquire
+ * @param ctx invocation context associated with this invocation
+ * @return true if all locks were acquired, false otherwise.
+ */
+ boolean lockAllAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx);
+
+ /**
+ * Releases locks on a given node and all children for a given owner.
+ *
+ * @param node node to unlock
+ * @param owner lock owner
+ */
+ void unlockAll(NodeSPI node, Object owner);
+
+ /**
+ * Releases locks on a given node and all children for all owners. Use with care.
+ *
+ * @param node node to unlock
+ */
+ void unlockAll(NodeSPI node);
+
+ /**
+ * Tests whether a given owner owns a lock of lockType on a particular Fqn.
+ *
+ * @param fqn fqn to test
+ * @param lockType type of lock to test for
+ * @param owner owner
+ * @return true if the owner does own the specified lock type on the specified node, false otherwise.
+ */
+ boolean ownsLock(Fqn fqn, LockType lockType, Object owner);
+
+ /**
+ * Tests whether a given owner owns any sort of lock on a particular Fqn.
+ *
+ * @param fqn fqn to test
+ * @param owner owner
+ * @return true if the owner does own the specified lock type on the specified node, false otherwise.
+ */
+ boolean ownsLock(Fqn fqn, Object owner);
+
+ /**
+ * Returns true if the node is locked (either for reading or writing) by anyone, and false otherwise.
+ *
+ * @param n node to inspect
+ * @return true of locked; false if not.
+ */
+ boolean isLocked(NodeSPI n);
+
+ /**
+ * Retrieves the write lock owner, if any, for the current Fqn.
+ *
+ * @param f Fqn to inspect
+ * @return the owner of the lock, or null if not locked.
+ */
+ Object getWriteOwner(Fqn f);
+
+ /**
+ * Retrieves the read lock owners, if any, for the current Fqn.
+ *
+ * @param f Fqn to inspect
+ * @return a collection of read lock owners, or an empty collection if not locked.
+ */
+ Collection<Object> getReadOwners(Fqn f);
+
+ /**
+ * Retrieves the write lock owner, if any, for the current Fqn.
+ *
+ * @param node the node to inspect
+ * @return the owner of the lock, or null if not locked.
+ */
+ Object getWriteOwner(NodeSPI node);
+
+ /**
+ * Retrieves the read lock owners, if any, for the current Fqn.
+ *
+ * @param node the node to inspect
+ * @return a collection of read lock owners, or an empty collection if not locked.
+ */
+ Collection<Object> getReadOwners(NodeSPI node);
+
+ /**
+ * Prints lock information about a node (and it's children) to a String.
+ *
+ * @param node node to inspect
+ */
+ String printLockInfo(NodeSPI node);
+}
Added: core/trunk/src/main/java/org/jboss/cache/lock/LockType.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockType.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockType.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -0,0 +1,12 @@
+package org.jboss.cache.lock;
+
+/**
+ * An enumeration to define different types of locks.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 2.2.0
+ */
+public enum LockType
+{
+ NONE, READ, WRITE
+}
Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockUtil.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockUtil.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockUtil.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -2,7 +2,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.statetransfer.StateTransferManager;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionTable;
@@ -21,7 +21,8 @@
int STATUS_BROKEN = Integer.MIN_VALUE;
}
- public static boolean breakTransactionLock(NodeLock lock,
+ public static boolean breakTransactionLock(NodeSPI node,
+ LockManager lockManager,
GlobalTransaction gtx,
boolean localTx,
TransactionTable tx_table, TransactionManager tm)
@@ -30,9 +31,9 @@
int tryCount = 0;
int lastStatus = TransactionLockStatus.STATUS_BROKEN;
- while (!broken && lock.isOwner(gtx))
+ while (!broken && lockManager.ownsLock(node.getFqn(), gtx))
{
- int status = breakTransactionLock(gtx, lock, tx_table, tm, localTx, lastStatus, tryCount);
+ int status = breakTransactionLock(gtx, node, lockManager, tx_table, tm, localTx, lastStatus, tryCount);
if (status == TransactionLockStatus.STATUS_BROKEN)
{
broken = true;
@@ -50,78 +51,6 @@
}
/**
- * Attempts to acquire a read lock on <code>node</code> for
- * <code>newOwner</code>, if necessary breaking locks held by
- * <code>curOwner</code>.
- *
- * @param node the node
- * @param lock the lock
- * @param curOwner the current owner
- * @param newOwner the new owner
- */
- private static boolean acquireLockFromOwner(Node node,
- NodeLock lock,
- Object curOwner,
- Object newOwner,
- TransactionTable tx_table,
- TransactionManager tm,
- Object localAddress)
- {
- if (trace)
- {
- log.trace("Attempting to acquire lock for node " + node.getFqn() +
- " from owner " + curOwner);
- }
-
- boolean acquired = false;
- boolean broken = false;
- int tryCount = 0;
- int lastStatus = TransactionLockStatus.STATUS_BROKEN;
-
- while (!broken && !acquired)
- {
- if (curOwner instanceof GlobalTransaction)
- {
- GlobalTransaction gtx = (GlobalTransaction) curOwner;
- boolean local = gtx.getAddress().equals(localAddress);
- int status = breakTransactionLock(gtx, lock, tx_table, tm, local, lastStatus, tryCount);
- if (status == TransactionLockStatus.STATUS_BROKEN)
- {
- broken = true;
- }
- else if (status != lastStatus)
- {
- tryCount = 0;
- }
- lastStatus = status;
- }
- else if (tryCount > 0)
- {
- lock.release(curOwner);
- broken = true;
- }
-
- if (broken && trace)
- {
- log.trace("Broke lock for node " + node.getFqn() +
- " held by owner " + curOwner);
- }
-
- try
- {
- acquired = lock.acquire(newOwner, 1, NodeLock.LockType.READ);
- }
- catch (Exception ignore)
- {
- }
-
- tryCount++;
- }
-
- return acquired;
- }
-
- /**
* Attempts to release the lock held by <code>gtx</code> by altering the
* underlying transaction. Different strategies will be employed
* depending on the status of the transaction and param
@@ -135,7 +64,6 @@
* {@link TransactionLockStatus#STATUS_BROKEN}.
*
* @param gtx the gtx holding the lock
- * @param lock the lock
* @param lastStatus the return value from a previous invocation of this
* method for the same lock, or Status.STATUS_UNKNOW
* for the first invocation.
@@ -147,15 +75,15 @@
* if the lock held by gtx was forcibly broken.
*/
private static int breakTransactionLock(GlobalTransaction gtx,
- NodeLock lock,
- TransactionTable tx_table,
+ NodeSPI node, LockManager lockManager,
+ TransactionTable transactionTable,
TransactionManager tm,
boolean localTx,
int lastStatus,
int tryCount)
{
int status = Status.STATUS_UNKNOWN;
- Transaction tx = tx_table.getLocalTransaction(gtx);
+ Transaction tx = transactionTable.getLocalTransaction(gtx);
if (tx != null)
{
try
@@ -196,7 +124,7 @@
{
// Something is wrong; our initial rollback call
// didn't generate a valid state change; just force it
- lock.release(gtx);
+ lockManager.unlock(node.getFqn(), gtx);
status = TransactionLockStatus.STATUS_BROKEN;
}
break;
@@ -213,7 +141,7 @@
case Status.STATUS_COMMITTED:
case Status.STATUS_ROLLEDBACK:
case Status.STATUS_NO_TRANSACTION:
- lock.release(gtx);
+ lockManager.unlock(node.getFqn(), gtx);
status = TransactionLockStatus.STATUS_BROKEN;
break;
@@ -245,14 +173,14 @@
// fall through and release
default:
- lock.release(gtx);
+ lockManager.unlock(node.getFqn(), gtx);
status = TransactionLockStatus.STATUS_BROKEN;
}
}
catch (Exception e)
{
log.error("Exception breaking locks held by " + gtx, e);
- lock.release(gtx);
+ lockManager.unlock(node.getFqn(), gtx);
status = TransactionLockStatus.STATUS_BROKEN;
}
}
@@ -260,11 +188,10 @@
{
// Race condition; globalTransaction was cleared from txTable.
// Just double check if globalTransaction still holds a lock
- if (gtx == lock.getWriterOwner()
- || lock.getReaderOwners().contains(gtx))
+ if (lockManager.ownsLock(node.getFqn(), gtx))
{
// perhaps we should throw an exception?
- lock.release(gtx);
+ lockManager.unlock(node.getFqn(), gtx);
status = TransactionLockStatus.STATUS_BROKEN;
}
}
Copied: core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java (from rev 5882, core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -0,0 +1,284 @@
+package org.jboss.cache.lock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.DataContainerImpl;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Start;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Mircea.Markus(a)jboss.com
+ * @since 2.2
+ */
+@SuppressWarnings("deprecation")
+public class NodeBasedLockManager implements LockManager
+{
+ private static final Log log = LogFactory.getLog(NodeBasedLockManager.class);
+ private static final boolean trace = log.isTraceEnabled();
+
+ protected Configuration configuration;
+ protected long lockAcquisitionTimeout;
+ protected DataContainerImpl dataContainer;
+ protected NodeSPI rootNode;
+
+ @Inject
+ public void inject(Configuration configuration, DataContainerImpl dataContainer)
+ {
+ this.configuration = configuration;
+ this.dataContainer = dataContainer;
+ }
+
+ @Start
+ public void setRootNode()
+ {
+ this.lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
+ rootNode = dataContainer.getRoot();
+ }
+
+ /**
+ * Internal method that acquires a lock and returns the lock object. Currently uses {@link IdentityLock} objects; may change in
+ * future to use standard JDK locks.
+ *
+ * @param fqn Fqn to lock
+ * @param lockType type of lock to acquire
+ * @param owner owner to acquire lock for
+ * @param timeout timeout
+ * @return lock if acquired, null otherwise.
+ */
+ private NodeLock acquireLock(Fqn fqn, LockType lockType, Object owner, long timeout)
+ {
+ return acquireLock(dataContainer.peek(fqn), lockType, owner, timeout);
+ }
+
+ private NodeLock acquireLock(NodeSPI node, LockType lockType, Object owner, long timeout)
+ {
+ NodeLock lock = node.getLock();
+ boolean acquired = false;
+ try
+ {
+ acquired = lock.acquire(owner, timeout, lockType);
+ }
+ catch (InterruptedException e)
+ {
+ // interrupted trying to acquire lock!
+ }
+
+ if (acquired)
+ return lock;
+ else
+ return null;
+ }
+
+ public Object getLockOwner(InvocationContext ctx)
+ {
+ return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
+ }
+
+ public boolean lock(Fqn fqn, LockType lockType, Object owner)
+ {
+ return acquireLock(fqn, lockType, owner, lockAcquisitionTimeout) != null;
+ }
+
+ public boolean lock(Fqn fqn, LockType lockType, Object owner, long timeout)
+ {
+ return acquireLock(fqn, lockType, owner, timeout) != null;
+ }
+
+ public boolean lockAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx)
+ {
+ return lockAndRecord(dataContainer.peek(fqn), lockType, ctx);
+ }
+
+ public boolean lockAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx)
+ {
+ NodeLock lock = acquireLock(node, lockType, getLockOwner(ctx), ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout));
+ if (lock != null)
+ {
+ if (ctx.getTransactionEntry() != null)
+ {
+ ctx.getTransactionEntry().addLock(lock);
+ }
+ else
+ {
+ ctx.addInvocationLockAcquired(lock);
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public void unlock(InvocationContext ctx)
+ {
+ List<NodeLock> locks = ctx.getTransactionEntry() != null ? ctx.getTransactionEntry().getLocks() : ctx.getInvocationLocksAcquired();
+
+ Object owner = getLockOwner(ctx);
+ // Copying out to an array is faster than creating an ArrayList and iterating,
+ // since list creation will just copy out to an array internally
+ IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
+ for (int i = lockArray.length - 1; i >= 0; i--)
+ {
+ if (trace)
+ log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + "), owner " + owner);
+ lockArray[i].release(owner);
+ }
+ locks.clear();
+ }
+
+ public void unlock(NodeLock lock, Object owner)
+ {
+ if (trace) log.trace("releasing lock for " + lock.getFqn() + " (" + lock + "), owner " + owner);
+ lock.release(owner);
+ }
+
+ public void unlock(Fqn fqn, Object owner)
+ {
+ unlock(dataContainer.peek(fqn).getLock(), owner);
+ }
+
+ public boolean lockAll(NodeSPI node, LockType lockType, Object owner)
+ {
+ return lockAll(node, lockType, owner, lockAcquisitionTimeout, false);
+ }
+
+ public boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout)
+ {
+ return lockAll(node, lockType, owner, timeout, false);
+ }
+
+ /**
+ * Locks all nodes, and returns the NodeLocks in a List. Returns null if the locks could not be acquired.
+ *
+ * @param node node to lock
+ * @param lockType type of lock to acquire
+ * @param owner lock owner
+ * @param timeout timeout
+ * @param excludeInternalFqns if true, internal Fqns are excluded.
+ * @return list of locks acquired, or null.
+ */
+ private List<NodeLock> lockAllNodes(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns)
+ {
+ List<NodeLock> locks = null;
+ try
+ {
+ locks = new ArrayList<NodeLock>(node.getLock().acquireAll(owner, timeout, lockType, excludeInternalFqns));
+ }
+ catch (InterruptedException e)
+ {
+ // interrupted
+ }
+ return locks;
+ }
+
+ public boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns)
+ {
+ return lockAllNodes(node, lockType, owner, timeout, excludeInternalFqns) != null;
+ }
+
+ public boolean lockAllAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx)
+ {
+ return lockAllAndRecord(dataContainer.peek(fqn), lockType, ctx);
+ }
+
+ public boolean lockAllAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx)
+ {
+ List<NodeLock> locks = lockAllNodes(node, lockType, getLockOwner(ctx), ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout), false);
+ if (locks == null) return false;
+
+ if (locks.size() > 0)
+ {
+ if (ctx.getGlobalTransaction() != null)
+ {
+ ctx.getTransactionEntry().addLocks(locks);
+ }
+ else
+ {
+ ctx.addInvocationLocksAcquired(locks);
+ }
+ }
+
+ return true;
+ }
+
+ public void unlockAll(NodeSPI node, Object owner)
+ {
+ // recursively visit node and all children, and release all locks held by a given owner.
+ node.getLock().releaseAll(owner);
+ }
+
+ public void unlockAll(NodeSPI node)
+ {
+ // recursively visit node and all children, and release all locks held by a given owner.
+ node.getLock().releaseAll();
+ }
+
+ public boolean ownsLock(Fqn fqn, LockType lockType, Object owner)
+ {
+ NodeLock lock = dataContainer.peek(fqn).getLock();
+ switch (lockType)
+ {
+ case READ:
+ return lock.isReadLocked() && lock.isOwner(owner);
+ case WRITE:
+ return lock.isWriteLocked() && lock.isOwner(owner);
+ case NONE:
+ default:
+ return false;
+ }
+ }
+
+ public boolean ownsLock(Fqn fqn, Object owner)
+ {
+ NodeSPI node = dataContainer.peek(fqn);
+ return node != null && node.getLock().isOwner(owner);
+ }
+
+ public boolean isLocked(NodeSPI n)
+ {
+ return n.getLock().isLocked();
+ }
+
+ public Object getWriteOwner(Fqn f)
+ {
+ return getWriteOwner(dataContainer.peek(f));
+ }
+
+ public Collection<Object> getReadOwners(Fqn f)
+ {
+ return getReadOwners(dataContainer.peek(f));
+ }
+
+ public Object getWriteOwner(NodeSPI node)
+ {
+ return node.getLock().getWriterOwner();
+ }
+
+ public Collection<Object> getReadOwners(NodeSPI node)
+ {
+ return node.getLock().getReaderOwners();
+ }
+
+ public String printLockInfo(NodeSPI node)
+ {
+ StringBuffer sb = new StringBuffer("\n");
+ int indent = 0;
+
+ for (Object n : node.getChildrenDirect())
+ {
+ ((NodeSPI) n).getLock().printLockInfo(sb, indent);
+ sb.append("\n");
+ }
+
+ return sb.toString();
+ }
+}
Modified: core/trunk/src/main/java/org/jboss/cache/lock/NodeLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/NodeLock.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/lock/NodeLock.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -11,10 +11,6 @@
*/
public interface NodeLock
{
- enum LockType
- {
- NONE, READ, WRITE
- }
Fqn getFqn();
@@ -97,7 +93,7 @@
*/
boolean isOwner(Object o);
- boolean acquire(Object caller, long timeout, NodeLock.LockType lock_type) throws LockingException, TimeoutException,
+ boolean acquire(Object caller, long timeout, LockType lock_type) throws LockingException, TimeoutException,
InterruptedException;
/**
@@ -108,11 +104,11 @@
* @param lock_type type of lock
* @return locks acquired
*/
- Set<NodeLock> acquireAll(Object caller, long timeout, NodeLock.LockType lock_type) throws LockingException, TimeoutException,
+ Set<NodeLock> acquireAll(Object caller, long timeout, LockType lock_type) throws LockingException, TimeoutException,
InterruptedException;
/**
- * Same as the overloaded {@link #acquire(Object, long, org.jboss.cache.lock.NodeLock.LockType)} except that you can
+ * Same as the overloaded {@link #acquire(Object, long, LockType)} except that you can
* optionally specify that internal Fqns - such as buddy backup subtrees - can be excluded when acquiring locks.
*
* @param caller lock owner
Added: core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -0,0 +1,316 @@
+package org.jboss.cache.lock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.factories.CommandsFactory;
+import org.jboss.cache.factories.annotations.Inject;
+import static org.jboss.cache.lock.LockType.WRITE;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.transaction.TransactionEntry;
+import org.jboss.cache.transaction.TransactionTable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Contains specific methods for the PessimisticLockInterceptor.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @deprecated will be removed with pessimistic locking
+ */
+@Deprecated
+@SuppressWarnings("deprecation")
+public class PessimisticNodeBasedLockManager extends NodeBasedLockManager
+{
+ private static final Log log = LogFactory.getLog(PessimisticNodeBasedLockManager.class);
+ private static final boolean trace = log.isTraceEnabled();
+ private CommandsFactory commandsFactory;
+
+ @Inject
+ private void injectCommandsFactory(CommandsFactory commandsFactory)
+ {
+ this.commandsFactory = commandsFactory;
+ }
+
+ /**
+ * A specific lock method for the PessimisticLockInterceptor. It should *not* be used anywhere else as it has very
+ * peculiar and specific characteristics.
+ * <p/>
+ * For implementations of this LockManager interface that are not intended for use with the PessimisticLockInterceptor,
+ * it is okay not to implement this method (a no-op).
+ * <p/>
+ *
+ * @param fqn Fqn to lock
+ * @param lockType Type of lock to acquire
+ * @param ctx invocation context
+ * @param createIfNotExists if true, nodes will be created if they do not exist.
+ * @param zeroLockTimeout if true uses 0 as a lock acquisition timeout
+ * @param acquireWriteLockOnParent if true, write locks are acquired on parent nodes when child nodes need write locks.
+ * @param reverseRemoveCheck if true, nodes that have been marked as removed in the current transaction may be reversed.
+ * @param createdNodes a list to which nodes created in this method may be added.
+ * @param skipNotification if true, node creation notifications are suppressed.
+ * @return true if successful; false otherwise.
+ * @throws InterruptedException if interrupted
+ */
+ public boolean lockPessimistically(InvocationContext ctx, Fqn fqn, LockType lockType,
+ boolean createIfNotExists, boolean zeroLockTimeout, boolean acquireWriteLockOnParent,
+ boolean reverseRemoveCheck, List<NodeSPI> createdNodes, boolean skipNotification) throws InterruptedException
+ {
+ if (fqn == null || configuration.getIsolationLevel() == IsolationLevel.NONE || ctx.isLockingSuppressed())
+ return false;
+
+ boolean created;
+ long timeout = zeroLockTimeout ? 0 : ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout);
+ // make sure we can bail out of this loop
+ long cutoffTime = System.currentTimeMillis() + timeout;
+ boolean firstTry = true;
+ do
+ {
+ // this is an additional check to make sure we don't try for too long.
+ if (!firstTry && System.currentTimeMillis() > cutoffTime)
+ {
+ throw new TimeoutException("Unable to acquire lock on Fqn " + fqn + " after " + timeout + " millis");
+ }
+
+ created = lock(ctx, fqn, lockType, createIfNotExists, timeout, acquireWriteLockOnParent, reverseRemoveCheck, createdNodes, skipNotification);
+ firstTry = false;
+ }
+ while (createIfNotExists && (dataContainer.peek(fqn, false, false) == null));// keep trying until we have the lock (fixes concurrent remove())
+ return created;
+ }
+
+
+ /**
+ * Acquires locks on the node and on its parrents. Read locks are acquired for exsiting ancestors, with two exceptions:
+ * 1) createIfNotExists is true. If an ancestor is created on the fly, then an WL is acquired by default
+ * 2) acquireWriteLockOnParent is true. If so AND {@link org.jboss.cache.Node#isLockForChildInsertRemove()} then a read
+ * lock will be aquired for the parent of the node.
+ *
+ * @param createIfNotExists if true, then missing nodes will be cretaed on the fly. If false, method returns if we
+ * reach a node that does not exists
+ * @param reverseRemoveCheck if true, will reverse removes if needed.
+ * @param createdNodes a list to which any nodes created can register their Fqns so that calling code is aware of which nodes have been newly created.
+ * @param skipNotification
+ */
+ private boolean lock(InvocationContext ctx, Fqn fqn, LockType lockType, boolean createIfNotExists, long timeout,
+ boolean acquireWriteLockOnParent, boolean reverseRemoveCheck, List<NodeSPI> createdNodes, boolean skipNotification)
+ throws TimeoutException, LockingException, InterruptedException
+ {
+ Thread currentThread = Thread.currentThread();
+ GlobalTransaction gtx = ctx.getGlobalTransaction();
+ boolean created = false;
+ // if the tx associated with the current thread is rolling back, barf! JBCACHE-923
+ if (gtx != null) TransactionTable.assertTransactionValid(ctx);
+
+ Object owner = (gtx != null) ? gtx : currentThread;
+ NodeSPI currentNode;
+ if (trace) log.trace("Attempting to lock node " + fqn + " for owner " + owner);
+ long expiryTime = System.currentTimeMillis() + timeout;
+ currentNode = rootNode;
+ NodeSPI parent = null;
+ Object childName = null;
+ int currentIndex = -1;
+ int targetFqnSize = fqn.size();
+
+ do
+ {
+ if (currentNode == null)
+ {
+ if (createIfNotExists)
+ {
+ // if the new node is to be marked as deleted, do not notify!
+ currentNode = parent.addChildDirect(childName, !skipNotification);
+ created = true;
+ if (trace) log.trace("Child node was null, so created child node " + childName);
+ if (createdNodes != null) createdNodes.add(currentNode);
+ }
+ else
+ {
+ if (trace)
+ log.trace("failed to find or create child " + childName + " of node " + parent);
+ return false;
+ }
+ }
+ else
+ {
+ if (!currentNode.isValid() && createIfNotExists) currentNode.setValid(true, false);
+ }
+
+ LockType lockTypeRequired = LockType.READ;
+ if (created || writeLockNeeded(ctx, lockType, currentIndex, acquireWriteLockOnParent, createIfNotExists, fqn, currentNode))
+ {
+ lockTypeRequired = WRITE;
+ }
+
+ Fqn currentNodeFqn = currentNode.getFqn();
+ // actually acquire the lock we need. This method blocks.
+ acquireNodeLock(ctx, currentNode, owner, gtx, lockTypeRequired, timeout);
+
+ manageReverseRemove(ctx, currentNode, reverseRemoveCheck, createdNodes);
+ // make sure the lock we acquired isn't on a deleted node/is an orphan!!
+ // look into invalidated nodes as well
+ NodeSPI repeek = dataContainer.peek(currentNodeFqn, true, true);
+ if (currentNode != repeek)
+ {
+ if (trace)
+ log.trace("Was waiting for and obtained a lock on a node that doesn't exist anymore! Attempting lock acquisition again.");
+ // we have an orphan!! Lose the unnecessary lock and re-acquire the lock (and potentially recreate the node).
+ // check if the parent exists!!
+ // look into invalidated nodes as well
+ currentNode.getLock().releaseAll(owner);
+ if (parent == null || dataContainer.peek(parent.getFqn(), true, true) == null)
+ {
+ // crap!
+ if (trace)
+ log.trace("Parent has been deleted again. Go through the lock method all over again.");
+ currentNode = rootNode;
+ currentIndex = -1;
+ parent = null;
+ }
+ else
+ {
+ currentNode = parent;
+ currentIndex--;
+ parent = null;
+ if (System.currentTimeMillis() > expiryTime)
+ {
+ throw new TimeoutException("Unable to acquire lock on child node " + Fqn.fromRelativeElements(currentNode.getFqn(), childName) + " after " + timeout + " millis.");
+ }
+ if (trace) log.trace("Moving one level up, current node is :" + currentNode);
+ }
+ }
+ else
+ {
+ // we have succeeded in acquiring this lock. Increment the current index since we have gained one level of depth in the tree.
+ currentIndex++;
+
+ // now test if this is the final level and if we can quit the loop:
+ //if (currentNodeFqn.equals(fqn))//we've just processed the last child
+ if (currentIndex == targetFqnSize)
+ {
+ break;
+ }
+ if (!fqn.isChildOrEquals(currentNode.getFqn())) // Does this ever happen? Perhaps with a move(), I suppose? - MS
+ {
+ String message = new StringBuffer("currentNode instance changed the FQN(").append(currentNode.getFqn())
+ .append(") and do not match the FQN on which we want to acquire lock(").append(fqn).append(")").toString();
+ log.trace(message);
+ throw new LockingException(message);
+ }
+ parent = currentNode;
+
+ childName = fqn.get(currentIndex);
+ currentNode = currentNode.getChildDirect(childName);
+ }
+ }
+ while (true);
+ return created;
+ }
+
+ /**
+ * Used by lock()
+ * Determins whter an arbitrary node from the supplied fqn needs an write lock.
+ */
+ private boolean writeLockNeeded(InvocationContext ctx, LockType lockType, int currentNodeIndex, boolean acquireWriteLockOnParent, boolean createIfNotExists, Fqn targetFqn, NodeSPI currentNode)
+ {
+ int treeNodeSize = targetFqn.size();
+ // write lock forced!!
+ boolean isTargetNode = currentNodeIndex == (treeNodeSize - 1);
+ if (isTargetNode && ctx.getOptionOverrides().isForceWriteLock()) return true;
+ //this can be injected, from the caller as a param named wlParent
+ if (currentNode.isLockForChildInsertRemove())
+ {
+ if (acquireWriteLockOnParent && currentNodeIndex == treeNodeSize - 2)
+ {
+ return true;// we're doing a remove and we've reached the PARENT node of the target to be removed.
+ }
+ if (!isTargetNode && dataContainer.peek(targetFqn.getAncestor(currentNodeIndex + 2), false, false) == null)
+ {
+ return createIfNotExists;// we're at a node in the tree, not yet at the target node, and we need to create the next node. So we need a WL here.
+ }
+ }
+ return lockType == WRITE && isTargetNode;//write lock explicitly requested and this is the target to be written to.
+ }
+
+ private void acquireNodeLock(InvocationContext ctx, NodeSPI node, Object owner, GlobalTransaction gtx, LockType lockType, long lockTimeout) throws LockingException, TimeoutException, InterruptedException
+ {
+ NodeLock lock = node.getLock();
+ boolean acquired = lock.acquire(owner, lockTimeout, lockType);
+ if (acquired)
+ {
+ // Record the lock for release on method return or tx commit/rollback
+ if (gtx != null)
+ {
+ ctx.getTransactionEntry().addLock(lock);
+ }
+ else
+ {
+ ctx.addInvocationLockAcquired(lock);
+ }
+ }
+ }
+
+ /**
+ * Test if this node needs to be 'undeleted'
+ * reverse the "remove" if the node has been previously removed in the same tx, if this operation is a put()
+ */
+ public void manageReverseRemove(InvocationContext ctx, NodeSPI childNode, boolean reverseRemoveCheck, List createdNodes)
+ {
+ if (ctx.getGlobalTransaction() != null) //if no tx then reverse remove does not make sense
+ {
+ Fqn fqn = childNode.getFqn();
+ TransactionEntry entry = ctx.getTransactionEntry();
+ boolean needToReverseRemove = reverseRemoveCheck && childNode.isDeleted() && entry != null && entry.getRemovedNodes().contains(fqn);
+ if (!needToReverseRemove) return;
+ childNode.markAsDeleted(false);
+ //if we'll rollback the tx data should be added to the node again
+ Map oldData = new HashMap(childNode.getDataDirect());
+ PutDataMapCommand command = commandsFactory.buildPutDataMapCommand(ctx.getGlobalTransaction(), fqn, oldData);
+ // txTable.get(gtx).addUndoOperation(command); --- now need to make sure this is added to the normal mods list instead
+ entry.addModification(command);
+ //we're prepared for rollback, now reset the node
+ childNode.clearDataDirect();
+ if (createdNodes != null)
+ {
+ createdNodes.add(childNode);
+ }
+ }
+ }
+
+ /**
+ * Acquires write locks on the node and all child nodes, adding children to the list of removed nodes in the context.
+ *
+ * @param node node to inspect
+ * @param ctx invocation context
+ * @param entry transaction entry
+ * @throws InterruptedException in the event of interruption
+ */
+ public void lockAllForRemoval(NodeSPI node, InvocationContext ctx, TransactionEntry entry) throws InterruptedException
+ {
+ if (node == null) return;
+
+ long timeout = ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout);
+ GlobalTransaction gtx = ctx.getGlobalTransaction();
+ Object owner = (gtx != null) ? gtx : Thread.currentThread();
+
+ Set<NodeLock> acquiredLocks = node.getLock().acquireAll(owner, timeout, WRITE);
+ if (acquiredLocks.size() > 0)
+ {
+ if (gtx != null)
+ {
+ ctx.getTransactionEntry().addLocks(acquiredLocks);
+ for (NodeLock l : acquiredLocks) entry.addRemovedNode(l.getFqn());
+ }
+ else
+ {
+ ctx.addInvocationLocksAcquired(acquiredLocks);
+ }
+ }
+ }
+}
Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferManager.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferManager.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -17,7 +17,8 @@
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.NonVolatile;
import org.jboss.cache.loader.CacheLoaderManager;
-import org.jboss.cache.lock.NodeLock;
+import org.jboss.cache.lock.LockManager;
+import static org.jboss.cache.lock.LockType.READ;
import org.jboss.cache.lock.TimeoutException;
import org.jboss.cache.marshall.Marshaller;
import org.jboss.cache.marshall.NodeData;
@@ -39,18 +40,20 @@
private Marshaller marshaller;
private RegionManager regionManager;
private Configuration configuration;
+ private LockManager lockManager;
public StateTransferManager()
{
}
@Inject
- public void injectDependencies(CacheSPI cache, Marshaller marshaller, RegionManager regionManager, Configuration configuration)
+ public void injectDependencies(CacheSPI cache, Marshaller marshaller, RegionManager regionManager, Configuration configuration, LockManager lockManager)
{
this.cache = cache;
this.regionManager = regionManager;
this.marshaller = marshaller;
this.configuration = configuration;
+ this.lockManager = lockManager;
}
public StateTransferManager(CacheSPI cache)
@@ -251,11 +254,11 @@
{
if (lockChildren)
{
- root.getLock().acquireAll(lockOwner, timeout, NodeLock.LockType.READ, true);
+ lockManager.lockAll(root, READ, lockOwner, timeout, true);
}
else
{
- root.getLock().acquire(lockOwner, timeout, NodeLock.LockType.READ);
+ lockManager.lock(Fqn.ROOT, READ, lockOwner, timeout);
}
}
catch (TimeoutException te)
@@ -289,11 +292,11 @@
{
if (childrenLocked)
{
- root.getLock().releaseAll(lockOwner);
+ lockManager.unlockAll(root, lockOwner);
}
else
{
- root.getLock().release(lockOwner);
+ lockManager.unlock(Fqn.ROOT, lockOwner);
}
}
catch (Throwable t)
Modified: core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/test/java/org/jboss/cache/DataContainerTest.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -75,7 +75,7 @@
Configuration config = new Configuration();
config.setNodeLockingOptimistic(false);
DataVersion dataVersion = new DefaultDataVersion(2);
- container.setDependencies(config, null);
+ container.setDependencies(config, null, null);
assert nodes.adfgNode == container.peekVersioned(nodes.adfg, dataVersion, true) : "if NOT opt locking same value as peek(boolean, boolean) expected";
//test optimistic locking with same version
@@ -89,7 +89,8 @@
{
container.peekVersioned(nodes.adfg, new DefaultDataVersion(1), true);
assert false : "exception expected as version changed.";
- } catch (CacheException e)
+ }
+ catch (CacheException e)
{
//expected
}
@@ -106,7 +107,8 @@
{
container.peekStrict(null, nodes.notExistent, true);
assert false : "excpetion expected as node does not exist";
- } catch (Exception e)
+ }
+ catch (Exception e)
{
//expected
}
@@ -289,16 +291,16 @@
}
/**
- * test {@link DataContainerImpl#createNodes(Fqn)}
+ * test {@link DataContainerImpl#createNodes(Fqn)}
*/
public void testCreateNodes()
{
Object[] objects = container.createNodes(Fqn.fromString("/a/x/y/z"));
List result = (List) objects[0];
assert result.size() == 3;
- assert ((NodeSPI)result.get(0)).getFqn().equals(Fqn.fromString("/a/x"));
- assert ((NodeSPI)result.get(1)).getFqn().equals(Fqn.fromString("/a/x/y"));
- assert ((NodeSPI)result.get(2)).getFqn().equals(Fqn.fromString("/a/x/y/z"));
+ assert ((NodeSPI) result.get(0)).getFqn().equals(Fqn.fromString("/a/x"));
+ assert ((NodeSPI) result.get(1)).getFqn().equals(Fqn.fromString("/a/x/y"));
+ assert ((NodeSPI) result.get(2)).getFqn().equals(Fqn.fromString("/a/x/y/z"));
NodeSPI target = (NodeSPI) objects[1];
assert target != null;
assert target.getFqn().toString().equals("/a/x/y/z");
Modified: core/trunk/src/test/java/org/jboss/cache/lock/AcquireAllTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/AcquireAllTest.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/test/java/org/jboss/cache/lock/AcquireAllTest.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -42,12 +42,12 @@
root = cache.getRoot();
NodeLock lock = root.getLock();
- lock.acquireAll(owner, 2000, NodeLock.LockType.READ);
+ lock.acquireAll(owner, 2000, LockType.READ);
lock.releaseAll(owner);
assertEquals(0, cache.getNumberOfLocksHeld());
- lock.acquireAll(owner, 2000, NodeLock.LockType.WRITE);
+ lock.acquireAll(owner, 2000, LockType.WRITE);
lock.releaseAll(owner);
assertEquals(0, cache.getNumberOfLocksHeld());
@@ -67,12 +67,12 @@
root = cache.getRoot();
NodeLock lock = root.getLock();
- lock.acquireAll(owner, 2000, NodeLock.LockType.READ);
+ lock.acquireAll(owner, 2000, LockType.READ);
lock.releaseAll(owner);
assertEquals(0, cache.getNumberOfLocksHeld());
- lock.acquireAll(owner, 2000, NodeLock.LockType.WRITE);
+ lock.acquireAll(owner, 2000, LockType.WRITE);
lock.releaseAll(owner);
assertEquals(0, cache.getNumberOfLocksHeld());
Modified: core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java 2008-05-23 16:41:43 UTC (rev 5886)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java 2008-05-23 17:15:52 UTC (rev 5887)
@@ -7,9 +7,10 @@
import org.jboss.cache.commands.VisitableCommand;
import org.jboss.cache.interceptors.OptimisticInterceptor;
import org.jboss.cache.interceptors.OptimisticLockingInterceptor;
+import org.jboss.cache.lock.LockType;
+import static org.jboss.cache.lock.LockType.READ;
+import static org.jboss.cache.lock.LockType.WRITE;
import org.jboss.cache.lock.NodeLock;
-import static org.jboss.cache.lock.NodeLock.LockType.READ;
-import static org.jboss.cache.lock.NodeLock.LockType.WRITE;
import org.jboss.cache.misc.TestingUtil;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod;
@@ -191,8 +192,8 @@
class LockReportInterceptor extends OptimisticInterceptor
{
- private Map<Fqn, NodeLock.LockType> expected = new HashMap<Fqn, NodeLock.LockType>();
- private Map<Fqn, NodeLock.LockType> actual = new HashMap<Fqn, NodeLock.LockType>();
+ private Map<Fqn, LockType> expected = new HashMap<Fqn, LockType>();
+ private Map<Fqn, LockType> actual = new HashMap<Fqn, LockType>();
void reset()
{
16 years, 7 months
JBoss Cache SVN: r5886 - core/trunk/src/test/java/org/jboss/cache/util/internals.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-05-23 12:41:43 -0400 (Fri, 23 May 2008)
New Revision: 5886
Modified:
core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java
Log:
JBCACHE-1338 - removed thread sleep statments
Modified: core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java 2008-05-23 14:49:47 UTC (rev 5885)
+++ core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java 2008-05-23 16:41:43 UTC (rev 5886)
@@ -8,6 +8,7 @@
import org.jboss.cache.misc.TestingUtil;
import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
import java.util.Timer;
/**
@@ -40,11 +41,18 @@
evictionThread.cancel();
}
- public void startEviction() throws Exception
+ public void startEviction()
{
- Method method = EvictionTimerTask.class.getDeclaredMethod("processRegions", null);
- method.setAccessible(true);
- method.invoke(timerTask);
+ try
+ {
+ Method method = EvictionTimerTask.class.getDeclaredMethod("processRegions", null);
+ method.setAccessible(true);
+ method.invoke(timerTask);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new IllegalStateException(e);
+ }
}
/**
16 years, 7 months
JBoss Cache SVN: r5885 - core/trunk/src/test/java/org/jboss/cache/api.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-05-23 10:49:47 -0400 (Fri, 23 May 2008)
New Revision: 5885
Modified:
core/trunk/src/test/java/org/jboss/cache/api/ResidentNodesTest.java
Log:
JBCACHE-1338 - removed thread sleep statments
Modified: core/trunk/src/test/java/org/jboss/cache/api/ResidentNodesTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/ResidentNodesTest.java 2008-05-23 14:30:16 UTC (rev 5884)
+++ core/trunk/src/test/java/org/jboss/cache/api/ResidentNodesTest.java 2008-05-23 14:49:47 UTC (rev 5885)
@@ -4,6 +4,7 @@
import org.jboss.cache.CacheSPI;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
+import org.jboss.cache.util.internals.EvictionController;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.EvictionConfig;
import org.jboss.cache.config.EvictionRegionConfig;
@@ -27,6 +28,7 @@
public class ResidentNodesTest
{
private CacheSPI<Object, Object> cache;
+ private EvictionController evController;
private final String TEST_NODES_ROOT = "residentNodesTest";
private Cache[] caches = {};
@@ -40,6 +42,7 @@
cache.getConfiguration().getEvictionConfig().setWakeupIntervalSeconds(1);
createNewRegion();
cache.start();
+ evController = new EvictionController(cache);
}
/**
@@ -91,7 +94,7 @@
cache.put(getSubFqn("/h"), "k_h", "v_h");
cache.put(getSubFqn("/i"), "k_i", "v_i");
- Thread.sleep(3000);//so that eviction is activated
+ evController.startEviction();
assertTrue(cache.exists(getSubFqn("/a")));
assertTrue(cache.exists(getSubFqn("/b")));
@@ -113,7 +116,9 @@
cache.put(getSubFqn("/b"), "k_b", "v_b");
cache.put(getSubFqn("/c"), "k_c", "v_c");
cache.put(getSubFqn("/d"), "k_d", "v_d");
- Thread.sleep(3000);//so that eviction is activated
+
+ evController.startEviction();
+
assertFalse(cache.exists(getSubFqn("/a")));
assertTrue(cache.exists(getSubFqn("/b")));
assertTrue(cache.exists(getSubFqn("/c")));
@@ -145,7 +150,7 @@
cache.getNode(getSubFqn("/a"));
cache.getNode(getSubFqn("/b"));
- TestingUtil.sleepThread(3000);//so that eviction is activated
+ evController.startEviction();
//a and b should exist as those were marked resident. Also they shouldn't be caunted as nodes in the eviction
// queue
16 years, 7 months
JBoss Cache SVN: r5884 - in core/trunk/src: test/java/org/jboss/cache/notifications and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-05-23 10:30:16 -0400 (Fri, 23 May 2008)
New Revision: 5884
Modified:
core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java
core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java
core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java
Log:
JBCACHE-1338 - NotifierImpl performance refactoring
Modified: core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java 2008-05-23 10:34:25 UTC (rev 5883)
+++ core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java 2008-05-23 14:30:16 UTC (rev 5884)
@@ -24,7 +24,6 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -51,8 +50,25 @@
NodeActivatedEvent.class, NodePassivatedEvent.class, NodeLoadedEvent.class, NodeEvictedEvent.class, TransactionRegisteredEvent.class, TransactionCompletedEvent.class, ViewChangedEvent.class, BuddyGroupChangedEvent.class
};
+ private final List<ListenerInvocation> cacheStartedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> cacheStoppedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> cacheBlockedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> cacheUnblockedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeCreatedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeRemovedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeVisitedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeModifiedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeMovedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeActivatedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodePassivatedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeLoadedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> nodeEvictedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> transactionRegisteredListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> transactionCompletedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> viewChangedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ private final List<ListenerInvocation> buddyGroupChangedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
- final Map<Class, List<ListenerInvocation>> listenerInvocations = new ConcurrentHashMap<Class, List<ListenerInvocation>>();
+ // final Map<Class, List<ListenerInvocation>> listenerInvocations = new ConcurrentHashMap<Class, List<ListenerInvocation>>();
private Cache cache;
private boolean useMarshalledValueMaps;
private Configuration config;
@@ -76,7 +92,7 @@
@Destroy
protected void destroy()
{
- listenerInvocations.clear();
+ removeAllCacheListeners();
}
@Start
@@ -133,16 +149,8 @@
private void addListenerInvocation(Class annotation, ListenerInvocation li)
{
- synchronized (listenerInvocations)
- {
- List<ListenerInvocation> l = listenerInvocations.get(annotation);
- if (l == null)
- {
- l = new CopyOnWriteArrayList<ListenerInvocation>();
- listenerInvocations.put(annotation, l);
- }
- l.add(li);
- }
+ List<ListenerInvocation> result = getListenersForAnnotation(annotation);
+ result.add(li);
}
/**
@@ -162,29 +170,19 @@
*/
public void removeCacheListener(Object listener)
{
- synchronized (listenerInvocations)
- {
- for (Class annotation : allowedMethodAnnotations) removeListenerInvocation(annotation, listener);
- }
+ for (Class annotation : allowedMethodAnnotations) removeListenerInvocation(annotation, listener);
}
private void removeListenerInvocation(Class annotation, Object listener)
{
if (listener == null) return;
-
- List<ListenerInvocation> l = listenerInvocations.get(annotation);
+ List<ListenerInvocation> l = getListenersForAnnotation(annotation);
Set<Object> markedForRemoval = new HashSet<Object>();
- if (l != null)
+ for (ListenerInvocation li : l)
{
- for (ListenerInvocation li : l)
- {
- if (listener.equals(li.target)) markedForRemoval.add(li);
- }
-
- l.removeAll(markedForRemoval);
-
- if (l.isEmpty()) listenerInvocations.remove(annotation);
+ if (listener.equals(li.target)) markedForRemoval.add(li);
}
+ l.removeAll(markedForRemoval);
}
/**
@@ -193,10 +191,23 @@
@Stop(priority = 99)
public void removeAllCacheListeners()
{
- synchronized (listenerInvocations)
- {
- listenerInvocations.clear();
- }
+ cacheStartedListeners.clear();
+ cacheStoppedListeners.clear();
+ cacheBlockedListeners.clear();
+ cacheUnblockedListeners.clear();
+ nodeCreatedListeners.clear();
+ nodeRemovedListeners.clear();
+ nodeVisitedListeners.clear();
+ nodeModifiedListeners.clear();
+ nodeMovedListeners.clear();
+ nodeActivatedListeners.clear();
+ nodePassivatedListeners.clear();
+ nodeLoadedListeners.clear();
+ nodeEvictedListeners.clear();
+ transactionRegisteredListeners.clear();
+ transactionCompletedListeners.clear();
+ viewChangedListeners.clear();
+ buddyGroupChangedListeners.clear();
}
/**
@@ -204,26 +215,30 @@
*/
public Set<Object> getCacheListeners()
{
- Set<Object> s = new HashSet<Object>();
- synchronized (listenerInvocations)
- {
- for (Class annotation : allowedMethodAnnotations)
- {
- List<ListenerInvocation> l = listenerInvocations.get(annotation);
- if (l != null)
- {
- for (ListenerInvocation li : l) s.add(li.target);
- }
- }
- }
- return Collections.unmodifiableSet(s);
+ Set<Object> result = new HashSet<Object>();
+ result.addAll(getListeningObjects(cacheStartedListeners));
+ result.addAll(getListeningObjects(cacheStoppedListeners));
+ result.addAll(getListeningObjects(cacheBlockedListeners));
+ result.addAll(getListeningObjects(cacheUnblockedListeners));
+ result.addAll(getListeningObjects(nodeCreatedListeners));
+ result.addAll(getListeningObjects(nodeRemovedListeners));
+ result.addAll(getListeningObjects(nodeVisitedListeners));
+ result.addAll(getListeningObjects(nodeModifiedListeners));
+ result.addAll(getListeningObjects(nodeMovedListeners));
+ result.addAll(getListeningObjects(nodeActivatedListeners));
+ result.addAll(getListeningObjects(nodePassivatedListeners));
+ result.addAll(getListeningObjects(nodeLoadedListeners));
+ result.addAll(getListeningObjects(nodeEvictedListeners));
+ result.addAll(getListeningObjects(transactionRegisteredListeners));
+ result.addAll(getListeningObjects(transactionCompletedListeners));
+ result.addAll(getListeningObjects(viewChangedListeners));
+ result.addAll(getListeningObjects(buddyGroupChangedListeners));
+ return Collections.unmodifiableSet(result);
}
public void notifyNodeCreated(Fqn fqn, boolean pre, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeCreated.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeCreatedListeners.isEmpty())
{
boolean originLocal = ctx.isOriginLocal();
Transaction tx = ctx.getTransaction();
@@ -235,16 +250,14 @@
e.setFqn(fqn);
e.setTransaction(tx);
e.setType(NODE_CREATED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeCreatedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodeModified(Fqn fqn, boolean pre, NodeModifiedEvent.ModificationType modificationType, Map data, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeModified.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeModifiedListeners.isEmpty())
{
boolean originLocal = ctx.isOriginLocal();
Map dataCopy = copy(data, useMarshalledValueMaps);
@@ -259,22 +272,19 @@
e.setModificationType(modificationType);
e.setData(dataCopy);
e.setType(NODE_MODIFIED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeModifiedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public boolean shouldNotifyOnNodeModified()
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeRemoved.class);
- return (listeners != null && !listeners.isEmpty());
+ return !nodeModifiedListeners.isEmpty();
}
public void notifyNodeRemoved(Fqn fqn, boolean pre, Map data, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeRemoved.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeRemovedListeners.isEmpty())
{
boolean originLocal = ctx.isOriginLocal();
Map dataCopy = copy(data, useMarshalledValueMaps);
@@ -288,16 +298,14 @@
e.setTransaction(tx);
e.setData(dataCopy);
e.setType(NODE_REMOVED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeRemovedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodeVisited(Fqn fqn, boolean pre, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeVisited.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeVisitedListeners.isEmpty())
{
Transaction tx = ctx.getTransaction();
InvocationContext backup = resetInvocationContext(ctx);
@@ -307,16 +315,14 @@
e.setFqn(fqn);
e.setTransaction(tx);
e.setType(NODE_VISITED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeVisitedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodeMoved(Fqn originalFqn, Fqn newFqn, boolean pre, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeMoved.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeMovedListeners.isEmpty())
{
boolean originLocal = ctx.isOriginLocal();
Transaction tx = ctx.getTransaction();
@@ -329,16 +335,14 @@
e.setTargetFqn(newFqn);
e.setTransaction(tx);
e.setType(NODE_MOVED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeMovedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodeEvicted(final Fqn fqn, final boolean pre, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeEvicted.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeEvictedListeners.isEmpty())
{
final boolean originLocal = ctx.isOriginLocal();
Transaction tx = ctx.getTransaction();
@@ -350,16 +354,14 @@
e.setFqn(fqn);
e.setTransaction(tx);
e.setType(NODE_EVICTED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeEvictedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodeLoaded(Fqn fqn, boolean pre, Map data, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeLoaded.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeLoadedListeners.isEmpty())
{
boolean originLocal = ctx.isOriginLocal();
Map dataCopy = copy(data, useMarshalledValueMaps);
@@ -373,16 +375,14 @@
e.setTransaction(tx);
e.setData(dataCopy);
e.setType(NODE_LOADED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeLoadedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodeActivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodeActivated.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodeActivatedListeners.isEmpty())
{
boolean originLocal = ctx.isOriginLocal();
Map dataCopy = copy(data, useMarshalledValueMaps);
@@ -396,16 +396,14 @@
e.setTransaction(tx);
e.setData(dataCopy);
e.setType(NODE_ACTIVATED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodeActivatedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyNodePassivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(NodePassivated.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!nodePassivatedListeners.isEmpty())
{
Map dataCopy = copy(data, useMarshalledValueMaps);
Transaction tx = ctx.getTransaction();
@@ -417,7 +415,7 @@
e.setTransaction(tx);
e.setData(dataCopy);
e.setType(NODE_PASSIVATED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : nodePassivatedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
@@ -428,14 +426,12 @@
@Start(priority = 99)
public void notifyCacheStarted()
{
- List<ListenerInvocation> listeners = listenerInvocations.get(CacheStarted.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!cacheStartedListeners.isEmpty())
{
EventImpl e = new EventImpl();
e.setCache(cache);
e.setType(CACHE_STARTED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : cacheStartedListeners) listener.invoke(e);
}
}
@@ -445,53 +441,45 @@
@Stop(priority = 98)
public void notifyCacheStopped()
{
- List<ListenerInvocation> listeners = listenerInvocations.get(CacheStopped.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!cacheStoppedListeners.isEmpty())
{
EventImpl e = new EventImpl();
e.setCache(cache);
e.setType(CACHE_STOPPED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : cacheStoppedListeners) listener.invoke(e);
}
}
public void notifyViewChange(final View newView, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(ViewChanged.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!viewChangedListeners.isEmpty())
{
InvocationContext backup = resetInvocationContext(ctx);
EventImpl e = new EventImpl();
e.setCache(cache);
e.setNewView(newView);
e.setType(VIEW_CHANGED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : viewChangedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyBuddyGroupChange(final BuddyGroup buddyGroup, boolean pre)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(BuddyGroupChanged.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!buddyGroupChangedListeners.isEmpty())
{
EventImpl e = new EventImpl();
e.setCache(cache);
e.setBuddyGroup(buddyGroup);
e.setPre(pre);
e.setType(BUDDY_GROUP_CHANGED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : buddyGroupChangedListeners) listener.invoke(e);
}
}
public void notifyTransactionCompleted(Transaction transaction, boolean successful, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(TransactionCompleted.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!transactionCompletedListeners.isEmpty())
{
boolean isOriginLocal = ctx.isOriginLocal();
InvocationContext backup = resetInvocationContext(ctx);
@@ -501,16 +489,14 @@
e.setTransaction(transaction);
e.setSuccessful(successful);
e.setType(TRANSACTION_COMPLETED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : transactionCompletedListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyTransactionRegistered(Transaction transaction, InvocationContext ctx)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(TransactionRegistered.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!transactionRegisteredListeners.isEmpty())
{
boolean isOriginLocal = ctx.isOriginLocal();
InvocationContext backup = resetInvocationContext(ctx);
@@ -519,36 +505,32 @@
e.setOriginLocal(isOriginLocal);
e.setTransaction(transaction);
e.setType(TRANSACTION_REGISTERED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : transactionRegisteredListeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
public void notifyCacheBlocked(boolean pre)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(CacheBlocked.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!cacheBlockedListeners.isEmpty())
{
EventImpl e = new EventImpl();
e.setCache(this.cache);
e.setPre(pre);
e.setType(CACHE_BLOCKED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : cacheBlockedListeners) listener.invoke(e);
}
}
public void notifyCacheUnblocked(boolean pre)
{
- List<ListenerInvocation> listeners = listenerInvocations.get(CacheUnblocked.class);
-
- if (listeners != null && !listeners.isEmpty())
+ if (!cacheUnblockedListeners.isEmpty())
{
EventImpl e = new EventImpl();
e.setCache(this.cache);
e.setPre(pre);
e.setType(CACHE_UNBLOCKED);
- for (ListenerInvocation listener : listeners) listener.invoke(e);
+ for (ListenerInvocation listener : cacheUnblockedListeners) listener.invoke(e);
}
}
@@ -603,7 +585,9 @@
*/
class ListenerInvocation
{
+
private final Object target;
+
private final Method method;
public ListenerInvocation(Object target, Method method)
@@ -632,6 +616,177 @@
removeCacheListener(this.target);
}
}
+
}
+ private List<ListenerInvocation> getListenersForAnnotation(Class annotation)
+ {
+ if (annotation == CacheStarted.class)
+ {
+ return cacheStartedListeners;
+ }
+ else if (annotation == CacheStopped.class)
+ {
+ return cacheStoppedListeners;
+ }
+ else if (annotation == CacheBlocked.class)
+ {
+ return cacheBlockedListeners;
+ }
+ else if (annotation == CacheUnblocked.class)
+ {
+ return cacheUnblockedListeners;
+ }
+ else if (annotation == NodeCreated.class)
+ {
+ return nodeCreatedListeners;
+ }
+ else if (annotation == NodeRemoved.class)
+ {
+ return nodeRemovedListeners;
+ }
+ else if (annotation == NodeVisited.class)
+ {
+ return nodeVisitedListeners;
+ }
+ else if (annotation == NodeModified.class)
+ {
+ return nodeModifiedListeners;
+ }
+ else if (annotation == NodeMoved.class)
+ {
+ return nodeMovedListeners;
+ }
+ else if (annotation == NodeActivated.class)
+ {
+ return nodeActivatedListeners;
+ }
+ else if (annotation == NodePassivated.class)
+ {
+ return nodePassivatedListeners;
+ }
+ else if (annotation == NodeLoaded.class)
+ {
+ return nodeLoadedListeners;
+ }
+ else if (annotation == NodeEvicted.class)
+ {
+ return nodeEvictedListeners;
+ }
+ else if (annotation == TransactionRegistered.class)
+ {
+ return transactionRegisteredListeners;
+ }
+ else if (annotation == TransactionCompleted.class)
+ {
+ return transactionCompletedListeners;
+ }
+ else if (annotation == ViewChanged.class)
+ {
+ return viewChangedListeners;
+ }
+ else if (annotation == BuddyGroupChanged.class)
+ {
+ return buddyGroupChangedListeners;
+ }
+ else
+ {
+ throw new RuntimeException("Unknown listener class: " + annotation);
+ }
+ }
+
+ private Collection getListeningObjects(List<ListenerInvocation> cacheStartedListeners)
+ {
+ Set result = new HashSet();
+ for (ListenerInvocation li : cacheStartedListeners)
+ {
+ result.add(li.target);
+ }
+ return result;
+ }
+
+ public List<ListenerInvocation> getCacheStartedListeners()
+ {
+ return cacheStartedListeners;
+ }
+
+ public List<ListenerInvocation> getCacheStoppedListeners()
+ {
+ return cacheStoppedListeners;
+ }
+
+ public List<ListenerInvocation> getCacheBlockedListeners()
+ {
+ return cacheBlockedListeners;
+ }
+
+ public List<ListenerInvocation> getCacheUnblockedListeners()
+ {
+ return cacheUnblockedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeCreatedListeners()
+ {
+ return nodeCreatedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeRemovedListeners()
+ {
+ return nodeRemovedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeVisitedListeners()
+ {
+ return nodeVisitedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeModifiedListeners()
+ {
+ return nodeModifiedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeMovedListeners()
+ {
+ return nodeMovedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeActivatedListeners()
+ {
+ return nodeActivatedListeners;
+ }
+
+ public List<ListenerInvocation> getNodePassivatedListeners()
+ {
+ return nodePassivatedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeLoadedListeners()
+ {
+ return nodeLoadedListeners;
+ }
+
+ public List<ListenerInvocation> getNodeEvictedListeners()
+ {
+ return nodeEvictedListeners;
+ }
+
+ public List<ListenerInvocation> getTransactionRegisteredListeners()
+ {
+ return transactionRegisteredListeners;
+ }
+
+ public List<ListenerInvocation> getTransactionCompletedListeners()
+ {
+ return transactionCompletedListeners;
+ }
+
+ public List<ListenerInvocation> getViewChangedListeners()
+ {
+ return viewChangedListeners;
+ }
+
+ public List<ListenerInvocation> getBuddyGroupChangedListeners()
+ {
+ return buddyGroupChangedListeners;
+ }
}
Modified: core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java 2008-05-23 10:34:25 UTC (rev 5883)
+++ core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java 2008-05-23 14:30:16 UTC (rev 5884)
@@ -180,9 +180,9 @@
{
Object l = new TestMultipleMethodsListener();
n.addCacheListener(l);
- List invocations = n.listenerInvocations.get(CacheStarted.class);
+ List invocations = n.getCacheStartedListeners();
assertEquals(1, invocations.size());
- invocations = n.listenerInvocations.get(CacheStopped.class);
+ invocations = n.getCacheStoppedListeners();
assertEquals(1, invocations.size());
assertEquals(1, n.getCacheListeners().size());
}
@@ -191,9 +191,9 @@
{
Object l = new TestMultipleAnnotationsOneMethodListener();
n.addCacheListener(l);
- List invocations = n.listenerInvocations.get(CacheStarted.class);
+ List invocations = n.getCacheStartedListeners();
assertEquals(1, invocations.size());
- invocations = n.listenerInvocations.get(CacheStopped.class);
+ invocations = n.getCacheStoppedListeners();
assertEquals(1, invocations.size());
assertEquals(1, n.getCacheListeners().size());
}
@@ -202,7 +202,7 @@
{
Object l = new TestMultipleMethodsOneAnnotationListener();
n.addCacheListener(l);
- List invocations = n.listenerInvocations.get(CacheStarted.class);
+ List invocations = n.getCacheStartedListeners();
assertEquals(2, invocations.size());
assertEquals(1, n.getCacheListeners().size());
}
Modified: core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java 2008-05-23 10:34:25 UTC (rev 5883)
+++ core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java 2008-05-23 14:30:16 UTC (rev 5884)
@@ -62,6 +62,7 @@
Map expected = new HashMap();
expected.put("k", "v");
notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, expected, ctx);
+ assert notifier.getNodeModifiedListeners().size() == 1;
assert allEventsListener.nodeModifiedEvent != null;
assert allEventsListener.nodeModifiedEvent.getData().equals(expected);
assert allEventsListener.nodeModifiedEvent.getModificationType() == NodeModifiedEvent.ModificationType.PUT_DATA;
16 years, 7 months
JBoss Cache SVN: r5883 - in core/trunk/src: main/java/org/jboss/cache/commands/remote and 5 other directories.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-05-23 06:34:25 -0400 (Fri, 23 May 2008)
New Revision: 5883
Added:
core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java
core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java
Removed:
core/trunk/src/test/java/org/jboss/cache/notifications/AnnotationsTest.java
Modified:
core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/commands/remote/AnnounceBuddyPoolNameCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/remote/AssignToBuddyGroupCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java
core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java
core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java
Log:
JBCACHE-1338 - added unit test for NotifierImpl class + small bug fixes + small refactorings
Modified: core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -630,8 +630,8 @@
{
flushBlockGate.close();
if (log.isDebugEnabled()) log.debug("Block received at " + getLocalAddress());
- notifier.notifyCacheBlocked(spi, true);
- notifier.notifyCacheBlocked(spi, false);
+ notifier.notifyCacheBlocked(true);
+ notifier.notifyCacheBlocked(false);
if (log.isDebugEnabled()) log.debug("Block processed at " + getLocalAddress());
}
@@ -643,8 +643,8 @@
{
if (log.isDebugEnabled()) log.debug("UnBlock received at " + getLocalAddress());
- notifier.notifyCacheUnblocked(spi, true);
- notifier.notifyCacheUnblocked(spi, false);
+ notifier.notifyCacheUnblocked(true);
+ notifier.notifyCacheUnblocked(false);
if (log.isDebugEnabled()) log.debug("UnBlock processed at " + getLocalAddress());
flushBlockGate.open();
Modified: core/trunk/src/main/java/org/jboss/cache/commands/remote/AnnounceBuddyPoolNameCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/remote/AnnounceBuddyPoolNameCommand.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/commands/remote/AnnounceBuddyPoolNameCommand.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -55,7 +55,6 @@
buddyManager.handlePoolNameBroadcast(address, buddyPoolName);
else if (log.isWarnEnabled())
log.warn("Received annouceBuddyPoolName call from [" + address + "] but buddy replication is not enabled on this node!");
-
return null;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/remote/AssignToBuddyGroupCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/remote/AssignToBuddyGroupCommand.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/commands/remote/AssignToBuddyGroupCommand.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -54,7 +54,6 @@
{
if (buddyManager != null)
buddyManager.handleAssignToBuddyGroup(group, state);
-
return null;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -60,10 +60,16 @@
{
oldData = new HashMap(existingData); // defensive copy
}
- notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, oldData == null ? Collections.emptyMap() : oldData, ctx);
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, oldData == null ? Collections.emptyMap() : oldData, ctx);
+ }
nodeSPI.putAllDirect(data);
- notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_MAP, nodeSPI.getDataDirect(), ctx);
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_MAP, nodeSPI.getDataDirect(), ctx);
+ }
return null;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -59,11 +59,17 @@
append(fqn).append("\", k=").append(key).append(", v=").append(value).append(")"));
}
NodeSPI n = dataContainer.peekStrict(globalTransaction, fqn, false);
- notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, n.getDataDirect(), ctx);
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, n.getDataDirect(), ctx);
+ }
oldValue = n.putDirect(key, value);
- Map newData = Collections.singletonMap(key, value);
- notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_DATA, newData, ctx);
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ Map newData = Collections.singletonMap(key, value);
+ notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_DATA, newData, ctx);
+ }
return oldValue;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -61,12 +61,16 @@
if (log.isDebugEnabled()) log.debug("node " + fqn + " not found");
return null;
}
- notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, n.getDataDirect(), ctx);
-
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, n.getDataDirect(), ctx);
+ }
this.oldValue = n.removeDirect(key);
-
- Map removedData = Collections.singletonMap(key, oldValue);
- notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, removedData, ctx);
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ Map removedData = Collections.singletonMap(key, oldValue);
+ notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, removedData, ctx);
+ }
return oldValue;
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -445,15 +445,19 @@
if (workspaceNode == null)
throw new NodeNotExistsException("optimisticCreateIfNotExistsInterceptor should have created this node!");
- Map addedData = Collections.singletonMap(key, value);
- // pre-notify
- notifier.notifyNodeModified(workspaceNode.getFqn(), true, PUT_DATA, workspaceNode.getData(), ctx);
+ if (notifier.shouldNotifyOnNodeModified())// pre-notify
+ {
+ notifier.notifyNodeModified(workspaceNode.getFqn(), true, PUT_DATA, workspaceNode.getData(), ctx);
+ }
Object old = workspaceNode.put(key, value);
workspace.addNode(workspaceNode);
- // post-notify
- notifier.notifyNodeModified(workspaceNode.getFqn(), false, PUT_DATA, addedData, ctx);
+ if (notifier.shouldNotifyOnNodeModified())// post-notify
+ {
+ Map addedData = Collections.singletonMap(key, value);
+ notifier.notifyNodeModified(workspaceNode.getFqn(), false, PUT_DATA, addedData, ctx);
+ }
return old;
}
@@ -497,15 +501,20 @@
{
if (workspaceNode == null) return null;
- // pre-notify
- notifier.notifyNodeModified(workspaceNode.getFqn(), true, REMOVE_DATA, workspaceNode.getData(), ctx);
+ if (notifier.shouldNotifyOnNodeModified())// pre-notify
+ {
+ notifier.notifyNodeModified(workspaceNode.getFqn(), true, REMOVE_DATA, workspaceNode.getData(), ctx);
+ }
Object old = workspaceNode.remove(removeKey);
workspace.addNode(workspaceNode);
- Map removedData = Collections.singletonMap(removeKey, old);
- // post-notify
- notifier.notifyNodeModified(workspaceNode.getFqn(), false, REMOVE_DATA, removedData, ctx);
+ if (notifier.shouldNotifyOnNodeModified())
+ {
+ Map removedData = Collections.singletonMap(removeKey, old);
+ // post-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), false, REMOVE_DATA, removedData, ctx);
+ }
return old;
}
Modified: core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/notifications/Notifier.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -1,99 +1,108 @@
-package org.jboss.cache.notifications;
-
-import org.jboss.cache.Fqn;
-import org.jboss.cache.InvocationContext;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.buddyreplication.BuddyGroup;
-import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.factories.annotations.Stop;
-import org.jboss.cache.notifications.event.NodeModifiedEvent;
-import org.jgroups.View;
-
-import javax.transaction.Transaction;
-import java.util.Map;
-
-/**
- * @author Mircea.Markus(a)jboss.com
- * @since 2.2
- */
-public interface Notifier
-{
- /**
- * Notifies all registered listeners of a nodeCreated event.
- */
- void notifyNodeCreated(Fqn fqn, boolean pre, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeModified event.
- */
- void notifyNodeModified(Fqn fqn, boolean pre, NodeModifiedEvent.ModificationType modificationType, Map data, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeRemoved event.
- */
- void notifyNodeRemoved(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeVisited event.
- */
- void notifyNodeVisited(Fqn fqn, boolean pre, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeMoved event.
- */
- void notifyNodeMoved(Fqn originalFqn, Fqn newFqn, boolean pre, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeEvicted event.
- */
- void notifyNodeEvicted(Fqn fqn, boolean pre, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeLoaded event.
- */
- void notifyNodeLoaded(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodeActivated event.
- */
- void notifyNodeActivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a nodePassivated event.
- */
- void notifyNodePassivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a viewChange event. Note that viewChange notifications are ALWAYS sent
- * immediately.
- */
- void notifyViewChange(View new_view, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a buddy group change event. Note that buddy group change notifications are ALWAYS sent
- * immediately.
- *
- * @param buddyGroup buddy group to set
- * @param pre if true, this has occured before the buddy group message is broadcast to the cluster
- */
- void notifyBuddyGroupChange(BuddyGroup buddyGroup, boolean pre);
-
- /**
- * Notifies all registered listeners of a transaction completion event.
- *
- * @param transaction the transaction that has just completed
- * @param successful if true, the transaction committed. If false, this is a rollback event
- */
- void notifyTransactionCompleted(Transaction transaction, boolean successful, InvocationContext ctx);
-
- /**
- * Notifies all registered listeners of a transaction registration event.
- *
- * @param transaction the transaction that has just completed
- */
- void notifyTransactionRegistered(Transaction transaction, InvocationContext ctx);
-
- void notifyCacheBlocked(CacheSPI cache, boolean pre);
-
- void notifyCacheUnblocked(CacheSPI cache, boolean pre);
-}
+package org.jboss.cache.notifications;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.buddyreplication.BuddyGroup;
+import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.factories.annotations.Stop;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jgroups.View;
+
+import javax.transaction.Transaction;
+import java.util.Map;
+
+/**
+ * Public interface with all allowed notifications.
+ *
+ * @author Mircea.Markus(a)jboss.com
+ * @since 2.2
+ */
+public interface Notifier
+{
+ /**
+ * Notifies all registered listeners of a nodeCreated event.
+ */
+ void notifyNodeCreated(Fqn fqn, boolean pre, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodeModified event.
+ */
+ void notifyNodeModified(Fqn fqn, boolean pre, NodeModifiedEvent.ModificationType modificationType, Map data, InvocationContext ctx);
+
+ /**
+ * When notifying about node modifications, in many scenarios there is a need of building a new Map object. If no
+ * listeners are registered for notification then it is pointless building this object - so guard the notification
+ * with this call.
+ */
+ public boolean shouldNotifyOnNodeModified();
+
+ /**
+ * Notifies all registered listeners of a nodeRemoved event.
+ */
+ void notifyNodeRemoved(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodeVisited event.
+ */
+ void notifyNodeVisited(Fqn fqn, boolean pre, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodeMoved event.
+ */
+ void notifyNodeMoved(Fqn originalFqn, Fqn newFqn, boolean pre, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodeEvicted event.
+ */
+ void notifyNodeEvicted(Fqn fqn, boolean pre, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodeLoaded event.
+ */
+ void notifyNodeLoaded(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodeActivated event.
+ */
+ void notifyNodeActivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a nodePassivated event.
+ */
+ void notifyNodePassivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a viewChange event. Note that viewChange notifications are ALWAYS sent
+ * immediately.
+ */
+ void notifyViewChange(View new_view, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a buddy group change event. Note that buddy group change notifications are ALWAYS sent
+ * immediately.
+ *
+ * @param buddyGroup buddy group to set
+ * @param pre if true, this has occured before the buddy group message is broadcast to the cluster
+ */
+ void notifyBuddyGroupChange(BuddyGroup buddyGroup, boolean pre);
+
+ /**
+ * Notifies all registered listeners of a transaction completion event.
+ *
+ * @param transaction the transaction that has just completed
+ * @param successful if true, the transaction committed. If false, this is a rollback event
+ */
+ void notifyTransactionCompleted(Transaction transaction, boolean successful, InvocationContext ctx);
+
+ /**
+ * Notifies all registered listeners of a transaction registration event.
+ *
+ * @param transaction the transaction that has just completed
+ */
+ void notifyTransactionRegistered(Transaction transaction, InvocationContext ctx);
+
+ void notifyCacheBlocked(boolean pre);
+
+ void notifyCacheUnblocked(boolean pre);
+}
Modified: core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -264,6 +264,12 @@
}
}
+ public boolean shouldNotifyOnNodeModified()
+ {
+ List<ListenerInvocation> listeners = listenerInvocations.get(NodeRemoved.class);
+ return (listeners != null && !listeners.isEmpty());
+ }
+
public void notifyNodeRemoved(Fqn fqn, boolean pre, Map data, InvocationContext ctx)
{
List<ListenerInvocation> listeners = listenerInvocations.get(NodeRemoved.class);
@@ -450,7 +456,7 @@
}
}
- public void notifyViewChange(final View new_view, InvocationContext ctx)
+ public void notifyViewChange(final View newView, InvocationContext ctx)
{
List<ListenerInvocation> listeners = listenerInvocations.get(ViewChanged.class);
@@ -459,7 +465,7 @@
InvocationContext backup = resetInvocationContext(ctx);
EventImpl e = new EventImpl();
e.setCache(cache);
- e.setNewView(new_view);
+ e.setNewView(newView);
e.setType(VIEW_CHANGED);
for (ListenerInvocation listener : listeners) listener.invoke(e);
restoreInvocationContext(backup);
@@ -487,13 +493,12 @@
if (listeners != null && !listeners.isEmpty())
{
- Transaction tx = ctx.getTransaction();
boolean isOriginLocal = ctx.isOriginLocal();
InvocationContext backup = resetInvocationContext(ctx);
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(isOriginLocal);
- e.setTransaction(tx);
+ e.setTransaction(transaction);
e.setSuccessful(successful);
e.setType(TRANSACTION_COMPLETED);
for (ListenerInvocation listener : listeners) listener.invoke(e);
@@ -507,41 +512,40 @@
if (listeners != null && !listeners.isEmpty())
{
- Transaction tx = ctx.getTransaction();
boolean isOriginLocal = ctx.isOriginLocal();
InvocationContext backup = resetInvocationContext(ctx);
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(isOriginLocal);
- e.setTransaction(tx);
+ e.setTransaction(transaction);
e.setType(TRANSACTION_REGISTERED);
for (ListenerInvocation listener : listeners) listener.invoke(e);
restoreInvocationContext(backup);
}
}
- public void notifyCacheBlocked(CacheSPI cache, boolean pre)
+ public void notifyCacheBlocked(boolean pre)
{
List<ListenerInvocation> listeners = listenerInvocations.get(CacheBlocked.class);
if (listeners != null && !listeners.isEmpty())
{
EventImpl e = new EventImpl();
- e.setCache(cache);
+ e.setCache(this.cache);
e.setPre(pre);
e.setType(CACHE_BLOCKED);
for (ListenerInvocation listener : listeners) listener.invoke(e);
}
}
- public void notifyCacheUnblocked(CacheSPI cache, boolean pre)
+ public void notifyCacheUnblocked(boolean pre)
{
List<ListenerInvocation> listeners = listenerInvocations.get(CacheUnblocked.class);
if (listeners != null && !listeners.isEmpty())
{
EventImpl e = new EventImpl();
- e.setCache(cache);
+ e.setCache(this.cache);
e.setPre(pre);
e.setType(CACHE_UNBLOCKED);
for (ListenerInvocation listener : listeners) listener.invoke(e);
Modified: core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -19,7 +19,7 @@
* @author Mircea.Markus(a)jboss.com
* @since 2.2
*/
-@Test(groups = {"functional"})
+@Test(groups = {"unit"})
public class InterceptorChainTest
{
private CommandInterceptor icInterceptor;
Deleted: core/trunk/src/test/java/org/jboss/cache/notifications/AnnotationsTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/notifications/AnnotationsTest.java 2008-05-21 16:59:54 UTC (rev 5882)
+++ core/trunk/src/test/java/org/jboss/cache/notifications/AnnotationsTest.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -1,349 +0,0 @@
-package org.jboss.cache.notifications;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.notifications.annotation.CacheListener;
-import org.jboss.cache.notifications.annotation.CacheStarted;
-import org.jboss.cache.notifications.annotation.CacheStopped;
-import org.jboss.cache.notifications.annotation.NodeMoved;
-import org.jboss.cache.notifications.event.Event;
-import org.jboss.cache.notifications.event.NodeMovedEvent;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.List;
-
-/**
- * Tests both correct and incorrect annotations for listeners
- *
- * @author <a href="mailto:manik@jboss.org">Manik Surtani</a>
- * @since 2.0.0
- */
-@Test(groups = {"functional"})
-public class AnnotationsTest
-{
- private NotifierImpl n;
-
- @BeforeMethod(alwaysRun = true)
- public void setUp()
- {
- Cache c = new DefaultCacheFactory().createCache(false);
- n = new NotifierImpl(c);
- }
-
- public void testControl()
- {
- Object l = new TestControlListener();
- n.addCacheListener(l);
- assertEquals(1, n.getCacheListeners().size());
- }
-
- public void testCacheListenerNoMethods()
- {
- Object l = new TestCacheListenerNoMethodsListener();
- n.addCacheListener(l);
- assertEquals("Hello", l.toString());
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty()); // since the valid listener has no methods to listen
- }
-
- public void testNonAnnotatedListener()
- {
- Object l = new TestNonAnnotatedListener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept an un-annotated cache listener");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testNonPublicListener()
- {
- Object l = new TestNonPublicListener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a private callback class");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testNonPublicListenerMethod()
- {
- Object l = new TestNonPublicListenerMethodListener();
- n.addCacheListener(l);
-
- // should not fail, should just not register anything
-
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testNonVoidReturnTypeMethod()
- {
- Object l = new TestNonVoidReturnTypeMethodListener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a listener method with a return type");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testIncorrectMethodSignature1()
- {
- Object l = new TestIncorrectMethodSignature1Listener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a cache listener with a bad method signature");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testIncorrectMethodSignature2()
- {
- Object l = new TestIncorrectMethodSignature2Listener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a cache listener with a bad method signature");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testIncorrectMethodSignature3()
- {
- Object l = new TestIncorrectMethodSignature3Listener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a cache listener with a bad method signature");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testUnassignableMethodSignature()
- {
- Object l = new TestUnassignableMethodSignatureListener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a cache listener with a bad method signature");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
- }
-
- public void testPartlyUnassignableMethodSignature()
- {
- Object l = new TestPartlyUnassignableMethodSignatureListener();
- try
- {
- n.addCacheListener(l);
- fail("Should not accept a cache listener with a bad method signature");
- }
- catch (IncorrectCacheListenerException icle)
- {
- // expected
- }
- }
-
- public void testMultipleMethods()
- {
- Object l = new TestMultipleMethodsListener();
- n.addCacheListener(l);
- List invocations = n.listenerInvocations.get(CacheStarted.class);
- assertEquals(1, invocations.size());
- invocations = n.listenerInvocations.get(CacheStopped.class);
- assertEquals(1, invocations.size());
- assertEquals(1, n.getCacheListeners().size());
- }
-
- public void testMultipleAnnotationsOneMethod()
- {
- Object l = new TestMultipleAnnotationsOneMethodListener();
- n.addCacheListener(l);
- List invocations = n.listenerInvocations.get(CacheStarted.class);
- assertEquals(1, invocations.size());
- invocations = n.listenerInvocations.get(CacheStopped.class);
- assertEquals(1, invocations.size());
- assertEquals(1, n.getCacheListeners().size());
- }
-
- public void testMultipleMethodsOneAnnotation()
- {
- Object l = new TestMultipleMethodsOneAnnotationListener();
- n.addCacheListener(l);
- List invocations = n.listenerInvocations.get(CacheStarted.class);
- assertEquals(2, invocations.size());
- assertEquals(1, n.getCacheListeners().size());
- }
-
- @CacheListener
- public class TestControlListener
- {
- @CacheStarted
- @CacheStopped
- public void callback(Event e)
- {
- System.out.println("Hello");
- }
- }
-
- @CacheListener
- public class TestCacheListenerNoMethodsListener
- {
- public String toString()
- {
- return "Hello";
- }
- }
-
- public class TestNonAnnotatedListener
- {
- public String toString()
- {
- return "Hello";
- }
- }
-
- @CacheListener
- protected class TestNonPublicListener
- {
- @CacheStarted
- public void callback()
- {
- }
- }
-
- @CacheListener
- public class TestNonPublicListenerMethodListener
- {
- @CacheStarted
- protected void callback(Event e)
- {
- }
- }
-
- @CacheListener
- public class TestNonVoidReturnTypeMethodListener
- {
- @CacheStarted
- public String callback(Event e)
- {
- return "Hello";
- }
- }
-
- @CacheListener
- public class TestIncorrectMethodSignature1Listener
- {
- @CacheStarted
- public void callback()
- {
- }
- }
-
- @CacheListener
- public class TestIncorrectMethodSignature2Listener
- {
- @CacheStarted
- public void callback(Event e, String s)
- {
- }
- }
-
- @CacheListener
- public class TestIncorrectMethodSignature3Listener
- {
- @CacheStarted
- public void callback(Event e, String... s)
- {
- }
- }
-
- @CacheListener
- public class TestUnassignableMethodSignatureListener
- {
- @CacheStarted
- public void callback(NodeMovedEvent nme)
- {
- }
- }
-
- @CacheListener
- public class TestPartlyUnassignableMethodSignatureListener
- {
- @NodeMoved
- @CacheStarted
- public void callback(NodeMovedEvent nme) // sig valid for NodeMoved but not CacheStarted
- {
- }
- }
-
- @CacheListener
- public class TestMultipleMethodsListener
- {
- @CacheStarted
- public void callback1(Event e)
- {
- }
-
- @CacheStopped
- public void callback2(Event e)
- {
- }
- }
-
- @CacheListener
- public class TestMultipleAnnotationsOneMethodListener
- {
- @CacheStopped
- @CacheStarted
- public void callback(Event nme)
- {
- }
- }
-
- @CacheListener
- public class TestMultipleMethodsOneAnnotationListener
- {
- @CacheStarted
- public void callback1(Event e)
- {
- }
-
- @CacheStarted
- public void callback2(Event e)
- {
- }
- }
-}
Copied: core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java (from rev 5878, core/trunk/src/test/java/org/jboss/cache/notifications/AnnotationsTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -0,0 +1,349 @@
+package org.jboss.cache.notifications;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.CacheStarted;
+import org.jboss.cache.notifications.annotation.CacheStopped;
+import org.jboss.cache.notifications.annotation.NodeMoved;
+import org.jboss.cache.notifications.event.Event;
+import org.jboss.cache.notifications.event.NodeMovedEvent;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+/**
+ * Tests both correct and incorrect annotations for listeners
+ *
+ * @author <a href="mailto:manik@jboss.org">Manik Surtani</a>
+ * @since 2.0.0
+ */
+@Test(groups = {"functional"})
+public class NotifierAnnotationsTest
+{
+ private NotifierImpl n;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp()
+ {
+ Cache c = new DefaultCacheFactory().createCache(false);
+ n = new NotifierImpl(c);
+ }
+
+ public void testControl()
+ {
+ Object l = new TestControlListener();
+ n.addCacheListener(l);
+ assertEquals(1, n.getCacheListeners().size());
+ }
+
+ public void testCacheListenerNoMethods()
+ {
+ Object l = new TestCacheListenerNoMethodsListener();
+ n.addCacheListener(l);
+ assertEquals("Hello", l.toString());
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty()); // since the valid listener has no methods to listen
+ }
+
+ public void testNonAnnotatedListener()
+ {
+ Object l = new TestNonAnnotatedListener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept an un-annotated cache listener");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testNonPublicListener()
+ {
+ Object l = new TestNonPublicListener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a private callback class");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testNonPublicListenerMethod()
+ {
+ Object l = new TestNonPublicListenerMethodListener();
+ n.addCacheListener(l);
+
+ // should not fail, should just not register anything
+
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testNonVoidReturnTypeMethod()
+ {
+ Object l = new TestNonVoidReturnTypeMethodListener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a listener method with a return type");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testIncorrectMethodSignature1()
+ {
+ Object l = new TestIncorrectMethodSignature1Listener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a cache listener with a bad method signature");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testIncorrectMethodSignature2()
+ {
+ Object l = new TestIncorrectMethodSignature2Listener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a cache listener with a bad method signature");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testIncorrectMethodSignature3()
+ {
+ Object l = new TestIncorrectMethodSignature3Listener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a cache listener with a bad method signature");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testUnassignableMethodSignature()
+ {
+ Object l = new TestUnassignableMethodSignatureListener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a cache listener with a bad method signature");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ assertTrue("No listeners should be registered.", n.getCacheListeners().isEmpty());
+ }
+
+ public void testPartlyUnassignableMethodSignature()
+ {
+ Object l = new TestPartlyUnassignableMethodSignatureListener();
+ try
+ {
+ n.addCacheListener(l);
+ fail("Should not accept a cache listener with a bad method signature");
+ }
+ catch (IncorrectCacheListenerException icle)
+ {
+ // expected
+ }
+ }
+
+ public void testMultipleMethods()
+ {
+ Object l = new TestMultipleMethodsListener();
+ n.addCacheListener(l);
+ List invocations = n.listenerInvocations.get(CacheStarted.class);
+ assertEquals(1, invocations.size());
+ invocations = n.listenerInvocations.get(CacheStopped.class);
+ assertEquals(1, invocations.size());
+ assertEquals(1, n.getCacheListeners().size());
+ }
+
+ public void testMultipleAnnotationsOneMethod()
+ {
+ Object l = new TestMultipleAnnotationsOneMethodListener();
+ n.addCacheListener(l);
+ List invocations = n.listenerInvocations.get(CacheStarted.class);
+ assertEquals(1, invocations.size());
+ invocations = n.listenerInvocations.get(CacheStopped.class);
+ assertEquals(1, invocations.size());
+ assertEquals(1, n.getCacheListeners().size());
+ }
+
+ public void testMultipleMethodsOneAnnotation()
+ {
+ Object l = new TestMultipleMethodsOneAnnotationListener();
+ n.addCacheListener(l);
+ List invocations = n.listenerInvocations.get(CacheStarted.class);
+ assertEquals(2, invocations.size());
+ assertEquals(1, n.getCacheListeners().size());
+ }
+
+ @CacheListener
+ public class TestControlListener
+ {
+ @CacheStarted
+ @CacheStopped
+ public void callback(Event e)
+ {
+ System.out.println("Hello");
+ }
+ }
+
+ @CacheListener
+ public class TestCacheListenerNoMethodsListener
+ {
+ public String toString()
+ {
+ return "Hello";
+ }
+ }
+
+ public class TestNonAnnotatedListener
+ {
+ public String toString()
+ {
+ return "Hello";
+ }
+ }
+
+ @CacheListener
+ protected class TestNonPublicListener
+ {
+ @CacheStarted
+ public void callback()
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestNonPublicListenerMethodListener
+ {
+ @CacheStarted
+ protected void callback(Event e)
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestNonVoidReturnTypeMethodListener
+ {
+ @CacheStarted
+ public String callback(Event e)
+ {
+ return "Hello";
+ }
+ }
+
+ @CacheListener
+ public class TestIncorrectMethodSignature1Listener
+ {
+ @CacheStarted
+ public void callback()
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestIncorrectMethodSignature2Listener
+ {
+ @CacheStarted
+ public void callback(Event e, String s)
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestIncorrectMethodSignature3Listener
+ {
+ @CacheStarted
+ public void callback(Event e, String... s)
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestUnassignableMethodSignatureListener
+ {
+ @CacheStarted
+ public void callback(NodeMovedEvent nme)
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestPartlyUnassignableMethodSignatureListener
+ {
+ @NodeMoved
+ @CacheStarted
+ public void callback(NodeMovedEvent nme) // sig valid for NodeMoved but not CacheStarted
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestMultipleMethodsListener
+ {
+ @CacheStarted
+ public void callback1(Event e)
+ {
+ }
+
+ @CacheStopped
+ public void callback2(Event e)
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestMultipleAnnotationsOneMethodListener
+ {
+ @CacheStopped
+ @CacheStarted
+ public void callback(Event nme)
+ {
+ }
+ }
+
+ @CacheListener
+ public class TestMultipleMethodsOneAnnotationListener
+ {
+ @CacheStarted
+ public void callback1(Event e)
+ {
+ }
+
+ @CacheStarted
+ public void callback2(Event e)
+ {
+ }
+ }
+}
Property changes on: core/trunk/src/test/java/org/jboss/cache/notifications/NotifierAnnotationsTest.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Added: core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/notifications/NotifierTest.java 2008-05-23 10:34:25 UTC (rev 5883)
@@ -0,0 +1,343 @@
+package org.jboss.cache.notifications;
+
+import static org.easymock.EasyMock.*;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import org.jboss.cache.Cache;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.buddyreplication.BuddyGroup;
+import org.jboss.cache.notifications.annotation.*;
+import org.jboss.cache.notifications.event.*;
+import org.jgroups.View;
+
+import javax.transaction.Transaction;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Tester class for {@link org.jboss.cache.notifications.NotifierImpl}.
+ *
+ * @author Mircea.Markus(a)jboss.com
+ * @since 2.2
+ */
+@Test(groups = "unit")
+public class NotifierTest
+{
+ private NotifierImpl notifier;
+ private Cache cache;
+ private InvocationContext ctx;
+ private AllEventsListener allEventsListener;
+ private Fqn fqn = Fqn.fromString("/a/b/c");
+
+ @BeforeMethod
+ public void setUp()
+ {
+ cache = createNiceMock(Cache.class);
+ notifier = new NotifierImpl(cache);
+ ctx = new InvocationContext();
+ allEventsListener = new AllEventsListener();
+ notifier.addCacheListener(allEventsListener);
+ }
+
+ public void testNotifyNodeCreated()
+ {
+ assert allEventsListener.nodeCreatedEvent == null;
+ notifier.notifyNodeCreated(fqn, true, ctx);
+ assert allEventsListener.nodeCreatedEvent != null;
+ assert allEventsListener.nodeCreatedEvent.getType() == Event.Type.NODE_CREATED;
+ }
+
+
+ public void testShouldNotifyOnNodeModified()
+ {
+ assert notifier.shouldNotifyOnNodeModified();
+ notifier.destroy();
+ assert !notifier.shouldNotifyOnNodeModified();
+ }
+
+ public void testNotifyNodeModified()
+ {
+ assert allEventsListener.nodeModifiedEvent == null;
+ Map expected = new HashMap();
+ expected.put("k", "v");
+ notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, expected, ctx);
+ assert allEventsListener.nodeModifiedEvent != null;
+ assert allEventsListener.nodeModifiedEvent.getData().equals(expected);
+ assert allEventsListener.nodeModifiedEvent.getModificationType() == NodeModifiedEvent.ModificationType.PUT_DATA;
+ }
+
+ public void testNotifyNodeRemoved()
+ {
+ assert allEventsListener.nodeRemoveEvent == null;
+ Map data = new HashMap();
+ data.put("k", "v");
+ notifier.notifyNodeRemoved(fqn, true, data, ctx);
+ assert allEventsListener.nodeRemoveEvent != null;
+ assert allEventsListener.nodeRemoveEvent.getData().equals(data);
+ assert allEventsListener.nodeRemoveEvent.getType() == Event.Type.NODE_REMOVED;
+ }
+
+ public void testNotifyNodeVisited()
+ {
+ assert allEventsListener.nodeVisistedEvent == null;
+ notifier.notifyNodeVisited(fqn, true, ctx);
+ assert allEventsListener.nodeVisistedEvent != null;
+ assert allEventsListener.nodeVisistedEvent.getType() == Event.Type.NODE_VISITED;
+ }
+
+ public void testNotifyNodeMoved()
+ {
+ assert allEventsListener.nodeMovedEvent == null;
+ Fqn second = Fqn.fromString("/a/s/f");
+ notifier.notifyNodeMoved(fqn, second, true, ctx);
+ assert allEventsListener.nodeMovedEvent != null;
+ assert allEventsListener.nodeMovedEvent.getFqn().equals(fqn);
+ assert allEventsListener.nodeMovedEvent.getTargetFqn().equals(second);
+ assert allEventsListener.nodeMovedEvent.getType() == Event.Type.NODE_MOVED;
+ }
+
+ public void testNotifyNodeEvicted()
+ {
+ assert allEventsListener.nodeEvictedEvent == null;
+ notifier.notifyNodeEvicted(fqn, true, ctx);
+ assert allEventsListener.nodeEvictedEvent != null;
+ assert allEventsListener.nodeEvictedEvent.getFqn().equals(fqn);
+ assert allEventsListener.nodeEvictedEvent.getType() == Event.Type.NODE_EVICTED;
+ }
+
+ public void testNotifyNodeLoaded()
+ {
+ assert allEventsListener.nodeLoadedEvent == null;
+ Map expected = new HashMap();
+ expected.put("key", "value");
+ notifier.notifyNodeLoaded(fqn, true, expected, ctx);
+ assert allEventsListener.nodeLoadedEvent != null;
+ assert allEventsListener.nodeLoadedEvent.getFqn().equals(fqn);
+ assert allEventsListener.nodeLoadedEvent.getData().equals(expected);
+ assert allEventsListener.nodeLoadedEvent.getType() == Event.Type.NODE_LOADED;
+ }
+
+ public void testNotifyNodeActivated()
+ {
+ assert allEventsListener.nodeActivatedEvent == null;
+ Map expected = new HashMap();
+ expected.put("key", "value");
+ notifier.notifyNodeActivated(fqn, true, expected, ctx);
+ assert allEventsListener.nodeActivatedEvent != null;
+ assert allEventsListener.nodeActivatedEvent.getFqn().equals(fqn);
+ assert allEventsListener.nodeActivatedEvent.getData().equals(expected);
+ assert allEventsListener.nodeActivatedEvent.getType() == Event.Type.NODE_ACTIVATED;
+ }
+
+ public void testNotifyNodePassivated()
+ {
+ assert allEventsListener.nodePassivatedEvent == null;
+ Map expected = new HashMap();
+ expected.put("key", "value");
+ notifier.notifyNodePassivated(fqn, true, expected, ctx);
+ assert allEventsListener.nodePassivatedEvent != null;
+ assert allEventsListener.nodePassivatedEvent.getFqn().equals(fqn);
+ assert allEventsListener.nodePassivatedEvent.getData().equals(expected);
+ assert allEventsListener.nodePassivatedEvent.getType() == Event.Type.NODE_PASSIVATED;
+ }
+
+ public void testNotifyCacheStarted()
+ {
+ assert allEventsListener.cacheStartedEvent == null;
+ notifier.notifyCacheStarted();
+ assert allEventsListener.cacheStartedEvent != null;
+ assert allEventsListener.cacheStartedEvent.getType() == Event.Type.CACHE_STARTED;
+ }
+
+ public void testNotifyCacheStopped()
+ {
+ assert allEventsListener.cacheStoppedEvent == null;
+ notifier.notifyCacheStopped();
+ assert allEventsListener.cacheStoppedEvent != null;
+ assert allEventsListener.cacheStoppedEvent.getType() == Event.Type.CACHE_STOPPED;
+ }
+
+ public void testNotifyViewChange()
+ {
+ assert allEventsListener.viewChanged == null;
+ View view = new View();
+ notifier.notifyViewChange(view, ctx);
+ assert allEventsListener.viewChanged != null;
+ assert allEventsListener.viewChanged.getNewView().equals(view);
+ assert allEventsListener.viewChanged.getType() == Event.Type.VIEW_CHANGED;
+ }
+
+ public void testNotifyBuddyGroupChange()
+ {
+ assert allEventsListener.buddyGroupChangedEvent == null;
+ BuddyGroup buddyGroup = new BuddyGroup();
+ notifier.notifyBuddyGroupChange(buddyGroup, true);
+ assert allEventsListener.buddyGroupChangedEvent != null;
+ assert allEventsListener.buddyGroupChangedEvent.getBuddyGroup().equals(buddyGroup);
+ assert allEventsListener.buddyGroupChangedEvent.getType() == Event.Type.BUDDY_GROUP_CHANGED;
+ }
+
+ public void testNotifyTransactionCompleted()
+ {
+ assert allEventsListener.transactionCompleted == null;
+ Transaction tx = createNiceMock(Transaction.class);
+ notifier.notifyTransactionCompleted(tx, false, ctx);
+ assert allEventsListener.transactionCompleted != null;
+ assert allEventsListener.transactionCompleted.getTransaction() == tx;
+ assert !allEventsListener.transactionCompleted.isSuccessful();
+ assert allEventsListener.transactionCompleted.getType() == Event.Type.TRANSACTION_COMPLETED;
+ }
+
+ public void testNotifyTransactionRegistered()
+ {
+ assert allEventsListener.transactionRegistered == null;
+ Transaction tx = createNiceMock(Transaction.class);
+ notifier.notifyTransactionRegistered(tx, ctx);
+ assert allEventsListener.transactionRegistered != null;
+ assert allEventsListener.transactionRegistered.getTransaction() == tx;
+ assert allEventsListener.transactionRegistered.getType() == Event.Type.TRANSACTION_REGISTERED;
+ }
+
+ public void testNotifyCacheBlocked()
+ {
+ assert allEventsListener.cacheBlockedEvent == null;
+ notifier.notifyCacheBlocked(false);
+ assert allEventsListener.cacheBlockedEvent != null;
+ assert !allEventsListener.cacheBlockedEvent.isPre();
+ assert allEventsListener.cacheBlockedEvent.getType() == Event.Type.CACHE_BLOCKED;
+ }
+
+ public void testNotifyCacheUnblocked()
+ {
+ assert allEventsListener.cacheUnblockedEvent== null;
+ notifier.notifyCacheUnblocked(false);
+ assert allEventsListener.cacheUnblockedEvent != null;
+ assert !allEventsListener.cacheUnblockedEvent.isPre();
+ assert allEventsListener.cacheUnblockedEvent.getType() == Event.Type.CACHE_UNBLOCKED;
+ }
+
+ @CacheListener
+ public static class AllEventsListener
+ {
+ CacheStartedEvent cacheStartedEvent;
+ CacheStoppedEvent cacheStoppedEvent;
+ CacheBlockedEvent cacheBlockedEvent;
+ CacheUnblockedEvent cacheUnblockedEvent;
+ NodeCreatedEvent nodeCreatedEvent;
+ NodeRemovedEvent nodeRemoveEvent;
+ NodeVisitedEvent nodeVisistedEvent;
+ NodeModifiedEvent nodeModifiedEvent;
+ NodeMovedEvent nodeMovedEvent;
+ NodeActivatedEvent nodeActivatedEvent;
+ NodePassivatedEvent nodePassivatedEvent;
+ NodeLoadedEvent nodeLoadedEvent;
+ NodeEvictedEvent nodeEvictedEvent;
+ TransactionRegisteredEvent transactionRegistered;
+ TransactionCompletedEvent transactionCompleted;
+ ViewChangedEvent viewChanged;
+ BuddyGroupChangedEvent buddyGroupChangedEvent;
+
+ @CacheStarted
+ public void onCacheStarted(CacheStartedEvent event)
+ {
+ cacheStartedEvent = event;
+ }
+
+ @CacheStopped
+ public void onCacheStopped(CacheStoppedEvent event)
+ {
+ cacheStoppedEvent = event;
+ }
+
+ @CacheBlocked
+ public void onCacheBlocked(CacheBlockedEvent event)
+ {
+ cacheBlockedEvent = event;
+ }
+
+ @CacheUnblocked
+ public void onCacheUnblocked(CacheUnblockedEvent event)
+ {
+ cacheUnblockedEvent = event;
+ }
+
+ @NodeCreated
+ public void onNodeCreated(NodeCreatedEvent event)
+ {
+ nodeCreatedEvent = event;
+ }
+
+ @NodeRemoved
+ public void onNodeRemoved(NodeRemovedEvent event)
+ {
+ nodeRemoveEvent = event;
+ }
+
+ @NodeVisited
+ public void onNodeVisited(NodeVisitedEvent event)
+ {
+ nodeVisistedEvent = event;
+ }
+
+ @NodeModified
+ public void onNodeModified(NodeModifiedEvent event)
+ {
+ nodeModifiedEvent = event;
+ }
+
+ @NodeMoved
+ public void onNodeMoved(NodeMovedEvent event)
+ {
+ nodeMovedEvent = event;
+ }
+
+ @NodeActivated
+ public void onNodeActivated(NodeActivatedEvent event)
+ {
+ nodeActivatedEvent = event;
+ }
+
+ @NodePassivated
+ public void onNodePassivated(NodePassivatedEvent event)
+ {
+ nodePassivatedEvent = event;
+ }
+
+ @NodeLoaded
+ public void onNodeLoaded(NodeLoadedEvent event)
+ {
+ nodeLoadedEvent = event;
+ }
+
+ @NodeEvicted
+ public void onNodeEvicted(NodeEvictedEvent event)
+ {
+ nodeEvictedEvent = event;
+ }
+
+ @TransactionRegistered
+ public void onTransactionRegistered(TransactionRegisteredEvent event)
+ {
+ transactionRegistered = event;
+ }
+
+ @TransactionCompleted
+ public void onTransactionCompleted(TransactionCompletedEvent event)
+ {
+ transactionCompleted = event;
+ }
+
+ @ViewChanged
+ public void onViewChanged(ViewChangedEvent event)
+ {
+ viewChanged = event;
+ }
+
+ @BuddyGroupChanged
+ public void onBuddyGroupChanged(BuddyGroupChangedEvent event)
+ {
+ buddyGroupChangedEvent = event;
+ }
+ }
+}
16 years, 7 months
JBoss Cache SVN: r5882 - in core/trunk/src/main/java/org/jboss/cache: lock and 1 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-05-21 12:59:54 -0400 (Wed, 21 May 2008)
New Revision: 5882
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java
Log:
Reorganised tx and locking methods
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -13,7 +13,9 @@
import org.jboss.cache.commands.tx.CommitCommand;
import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
+import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.lock.LockManager;
import static org.jboss.cache.lock.NodeLock.LockType.READ;
import static org.jboss.cache.lock.NodeLock.LockType.WRITE;
import org.jboss.cache.optimistic.TransactionWorkspace;
@@ -31,7 +33,14 @@
public class OptimisticLockingInterceptor extends OptimisticInterceptor
{
private long lockAcquisitionTimeout;
+ private LockManager lockManager;
+ @Inject
+ private void injectLockManager(LockManager lockManager)
+ {
+ this.lockManager = lockManager;
+ }
+
@Start
private void init()
{
@@ -134,7 +143,10 @@
try
{
TransactionEntry entry = ctx.getTransactionEntry();
- entry.releaseAllLocksFIFO(gtx);
+ if (entry != null)
+ {
+ lockManager.releaseLocks(entry.getLocks(), ctx.getGlobalTransaction());
+ }
}
catch (Exception e)
{
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -7,7 +7,10 @@
import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.*;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.config.Option;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.OptimisticTransactionEntry;
@@ -139,10 +142,10 @@
@Override
protected void cleanupStaleLocks(InvocationContext ctx) throws Throwable
{
+ super.cleanupStaleLocks(ctx);
TransactionEntry entry = ctx.getTransactionEntry();
if (entry != null)
{
- entry.releaseAllLocksLIFO(ctx.getGlobalTransaction());
((OptimisticTransactionEntry) entry).getTransactionWorkSpace().clearNodes();
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -20,16 +20,20 @@
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.*;
+import org.jboss.cache.commands.write.EvictCommand;
+import org.jboss.cache.commands.write.MoveCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutForExternalReadCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.interceptors.base.PostProcessingCommandInterceptor;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.lock.LockManager;
import org.jboss.cache.lock.NodeLock;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionEntry;
-import org.jboss.cache.transaction.TransactionTable;
import java.util.LinkedList;
import java.util.List;
@@ -53,25 +57,16 @@
*/
public class PessimisticLockInterceptor extends PostProcessingCommandInterceptor
{
- private TransactionTable txTable;
private DataContainerImpl dataContainer;
private LockManager lockManager;
- private long lockAcquisitionTimeout;
@Inject
- public void injectDependencies(DataContainerImpl dataContainer, TransactionTable txTable, LockManager lockManager)
+ public void injectDependencies(DataContainerImpl dataContainer, LockManager lockManager)
{
this.dataContainer = dataContainer;
- this.txTable = txTable;
this.lockManager = lockManager;
}
- @Start
- private void init()
- {
- lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
- }
-
@Override
protected Object handlePutDataMapCommand(InvocationContext ctx, PutDataMapCommand command) throws Throwable
{
@@ -125,7 +120,7 @@
// commit propagated up from the tx interceptor
commit(ctx.getTransactionEntry(), ctx.getGlobalTransaction());
Object retVal = invokeNextInterceptor(ctx, command);
- txTable.cleanup(ctx.getGlobalTransaction());
+ lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(), ctx.getGlobalTransaction());
return retVal;
}
@@ -135,7 +130,7 @@
commit(ctx.getTransactionEntry(), command.getGlobalTransaction());
if (trace) log.trace("bypassed locking as method commit() doesn't require locking");
Object retVal = invokeNextInterceptor(ctx, command);
- txTable.cleanup(command.getGlobalTransaction());
+ lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(), ctx.getGlobalTransaction());
return retVal;
}
@@ -165,7 +160,7 @@
log.trace("bypassed locking as method rollback() doesn't require locking");
}
Object retVal = invokeNextInterceptor(ctx, command);
- txTable.cleanup(command.getGlobalTransaction());
+ lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(), ctx.getGlobalTransaction());
return retVal;
}
@@ -173,12 +168,11 @@
protected Object handleMoveCommand(InvocationContext ctx, MoveCommand command) throws Throwable
{
if (ctx.isLockingSuppressed()) return invokeNextInterceptor(ctx, command);
- long timeout = ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout);
// this call will ensure the node gets a WL and it's current parent gets RL.
if (trace) log.trace("Attempting to get WL on node to be moved [" + command.getFqn() + "]");
if (command.getFqn() != null && !(configuration.getIsolationLevel() == IsolationLevel.NONE))
{
- lockManager.lock(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, timeout, true, false, null, false);
+ lockManager.acquireLocksWithTimeout(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, false, true, false, null, false);
if (ctx.getGlobalTransaction() != null)
{
ctx.getTransactionEntry().addRemovedNode(command.getFqn());
@@ -189,7 +183,7 @@
{
//now for an RL for the new parent.
if (trace) log.trace("Attempting to get RL on new parent [" + command.getTo() + "]");
- lockManager.lock(ctx, command.getTo(), NodeLock.LockType.READ, false, timeout, false, false, null, false);
+ lockManager.acquireLocksWithTimeout(ctx, command.getTo(), NodeLock.LockType.READ, false, false, false, false, null, false);
lockManager.acquireLocksOnChildren(dataContainer.peek(command.getTo(), true, false), NodeLock.LockType.READ, ctx);
}
Object retValue = invokeNextInterceptor(ctx, command);
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -19,12 +19,18 @@
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.*;
+import org.jboss.cache.commands.write.CreateNodeCommand;
+import org.jboss.cache.commands.write.InvalidateCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.config.Option;
import org.jboss.cache.factories.CommandsFactory;
import org.jboss.cache.factories.ComponentRegistry;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.lock.LockManager;
import org.jboss.cache.notifications.NotifierImpl;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionEntry;
@@ -70,17 +76,19 @@
private long commits = 0;
private long rollbacks = 0;
protected boolean optimistic = false;
+ private LockManager lockManager;
@Inject
public void intialize(RPCManager rpcManager,
NotifierImpl notifier, InvocationContextContainer icc,
- CommandsFactory factory, ComponentRegistry componentRegistry)
+ CommandsFactory factory, ComponentRegistry componentRegistry, LockManager lockManager)
{
this.commandsFactory = factory;
this.rpcManager = rpcManager;
this.notifier = notifier;
this.invocationContextContainer = icc;
this.componentRegistry = componentRegistry;
+ this.lockManager = lockManager;
}
@Override
@@ -592,7 +600,10 @@
protected void cleanupStaleLocks(InvocationContext ctx) throws Throwable
{
TransactionEntry entry = ctx.getTransactionEntry();
- if (entry != null) entry.releaseAllLocksLIFO(ctx.getGlobalTransaction());
+ if (entry != null)
+ {
+ lockManager.releaseLocks(entry.getLocks(), ctx.getGlobalTransaction());
+ }
}
/**
Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -94,8 +94,8 @@
* @param createdNodes a list to which any nodes created can register their Fqns so that calling code is aware of which nodes have been newly created.
* @param skipNotification
*/
- public boolean lock(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType, boolean createIfNotExists, long timeout,
- boolean acquireWriteLockOnParent, boolean reverseRemoveCheck, List<NodeSPI> createdNodes, boolean skipNotification)
+ private boolean lock(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType, boolean createIfNotExists, long timeout,
+ boolean acquireWriteLockOnParent, boolean reverseRemoveCheck, List<NodeSPI> createdNodes, boolean skipNotification)
throws TimeoutException, LockingException, InterruptedException
{
Thread currentThread = Thread.currentThread();
@@ -204,7 +204,8 @@
childName = fqn.get(currentIndex);
currentNode = currentNode.getChildDirect(childName);
}
- } while (true);
+ }
+ while (true);
return created;
}
@@ -242,7 +243,7 @@
// Record the lock for release on method return or tx commit/rollback
if (gtx != null)
{
- txTable.recordNodeLock(gtx, lock);
+ ctx.getTransactionEntry().addLock(lock);
}
else
{
@@ -308,7 +309,7 @@
{
if (gtx != null)
{
- txTable.addLocks(gtx, acquiredLocks);
+ ctx.getTransactionEntry().addLocks(acquiredLocks);
if (addChildrenToDeletedList)
{
for (NodeLock l : acquiredLocks)
@@ -323,4 +324,20 @@
}
}
}
+
+ /**
+ * Releases all locks held by the owner, in reverse order of creation.
+ */
+ public void releaseLocks(List<NodeLock> locks, Object owner)
+ {
+ // Copying out to an array is faster than creating an ArrayList and iterating,
+ // since list creation will just copy out to an array internally
+ IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
+ for (int i = lockArray.length - 1; i >= 0; i--)
+ {
+ if (trace) log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + ")");
+ lockArray[i].release(owner);
+ }
+ locks.clear();
+ }
}
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -213,53 +213,6 @@
}
/**
- * Releases all locks held by the owner, in reverse order of creation.
- * Clears the list of locks held.
- */
- public void releaseAllLocksLIFO(Object owner)
- {
-
- synchronized (locks)
- {
- // Copying out to an array is faster than creating an ArrayList and iterating,
- // since list creation will just copy out to an array internally
- IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
- for (int i = lockArray.length - 1; i >= 0; i--)
- {
- if (trace)
- {
- log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + ")");
- }
- lockArray[i].release(owner);
- }
- locks.clear();
- }
- }
-
- /**
- * Releases all locks held by the owner, in order of creation.
- * Does not clear the list of locks held.
- */
- public void releaseAllLocksFIFO(Object owner)
- {
- // I guess a copy would work as well
- // This seems fairly safe though
- synchronized (locks)
- {
- for (NodeLock lock : locks)
- {
- lock.release(owner);
- if (trace)
- {
- log.trace("releasing lock for " + lock.getFqn() + " (" + lock + ")");
- }
- }
-
- locks.clear();
- }
- }
-
- /**
* Gets the value of the forceAsyncReplication flag. Used by ReplicationInterceptor and OptimisticReplicationInterceptor
* when dealing with {@link org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
* a transactional context.
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java 2008-05-21 16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java 2008-05-21 16:59:54 UTC (rev 5882)
@@ -15,14 +15,12 @@
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.NonVolatile;
import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.lock.NodeLock;
import org.jgroups.Address;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
-import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -200,45 +198,6 @@
}
/**
- * Adds a lock to the global transaction.
- */
- public void addLock(GlobalTransaction gtx, NodeLock l)
- {
- TransactionEntry entry = get(gtx);
- if (entry == null)
- {
- throw new CacheException("Unable to record lock for transaction " + gtx + " since no transaction entry exists!");
- }
- entry.addLock(l);
- }
-
- /**
- * Adds a collection of locks to the global transaction.
- */
- public void addLocks(GlobalTransaction gtx, Collection<NodeLock> locks)
- {
- TransactionEntry entry = get(gtx);
- if (entry == null)
- {
- log.error("transaction entry not found for (globalTransaction=" + gtx + ")");
- return;
- }
- entry.addLocks(locks);
- }
-
- public void cleanup(GlobalTransaction gtx)
- {
- if (trace) log.trace("Cleaning up locks for globalTransaction " + gtx);
- TransactionEntry entry = this.get(gtx);
- // Let's do it in stack style, LIFO
- if (entry != null)
- entry.releaseAllLocksLIFO(gtx);
- else
- log.error("No transaction entry present!!");
- }
-
-
- /**
* Returns summary debug information.
*/
@Override
@@ -274,24 +233,6 @@
}
/**
- * Add the lock to the list of locks maintained for this transaction
- * (needed for release of locks on commit or rollback)
- */
- public void recordNodeLock(GlobalTransaction gtx, NodeLock lock)
- {
- try
- {
- addLock(gtx, lock);
- }
- catch (CacheException e)
- {
- // may happen, if the transaction entry does not exist
- lock.release(gtx);
- throw e;
- }
- }
-
- /**
* Returns the transaction associated with the current thread.
* If a local transaction exists, but doesn't yet have a mapping to a
* GlobalTransaction, a new GlobalTransaction will be created and mapped to
16 years, 7 months
JBoss Cache SVN: r5881 - in core/trunk/src: main/java/org/jboss/cache/commands/remote and 10 other directories.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-05-21 12:12:49 -0400 (Wed, 21 May 2008)
New Revision: 5881
Added:
core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveNodeCommandTest.java
Modified:
core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java
core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/PutForExternalReadCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java
core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java
core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java
core/trunk/src/test/java/org/jboss/cache/commands/write/PutDataMapCommandTest.java
core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java
core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveKeyCommandTest.java
core/trunk/src/test/java/org/jboss/cache/interceptors/EvictionInterceptorTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/ActiveInactiveTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller210Test.java
core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java
core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java
core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java
Log:
JBCACHE-1338 - added unit tests for write commands and write commands refactorings
Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -63,32 +63,28 @@
public Object visitPutDataMapCommand(InvocationContext ctx, PutDataMapCommand command) throws Throwable
{
Fqn transformed = getBackupFqn(command.getFqn());
- return factory.buildPutDataMapCommand(null, transformed, command.getData(),
- command.isCreateUndoOps(), command.isEraseContents());
+ return factory.buildPutDataMapCommand(null, transformed, command.getData());
}
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable
{
Fqn transformed = getBackupFqn(command.getFqn());
- return factory.buildPutKeyValueCommand(null, transformed, command.getKey(),
- command.getValue(), command.isCreateUndoOps());
+ return factory.buildPutKeyValueCommand(null, transformed, command.getKey(), command.getValue());
}
@Override
public Object visitPutForExternalReadCommand(InvocationContext ctx, PutForExternalReadCommand command) throws Throwable
{
Fqn transformed = getBackupFqn(command.getFqn());
- return factory.buildPutForExternalReadCommand(null, transformed, command.getKey(),
- command.getValue(), command.isCreateUndoOps());
+ return factory.buildPutForExternalReadCommand(null, transformed, command.getKey(), command.getValue());
}
@Override
public Object visitRemoveNodeCommand(InvocationContext ctx, RemoveNodeCommand command) throws Throwable
{
Fqn transformed = getBackupFqn(command.getFqn());
- return factory.buildRemoveNodeCommand(command.getGlobalTransaction(), transformed, command.isEviction(),
- command.isSkipSendingNodeEvents(), command.isCreateUndoOps());
+ return factory.buildRemoveNodeCommand(command.getGlobalTransaction(), transformed);
}
@Override
Modified: core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -68,10 +68,6 @@
/**
* Performs a cleanup on nodes that would have been previously gravitated away from the current cache instance.
- *
- * @param ctx invocation context, ignored
- * @return null
- * @throws Throwable
*/
public Object perform(InvocationContext ctx) throws Throwable
{
@@ -128,7 +124,7 @@
private boolean executeRemove(GlobalTransaction gtx, Fqn toRemove) throws Throwable
{
Object result;
- RemoveNodeCommand removeBackupCommand = commandsFactory.buildRemoveNodeCommand(gtx, toRemove, true, true, false);
+ RemoveNodeCommand removeBackupCommand = commandsFactory.buildRemoveNodeCommand(gtx, toRemove);
InvocationContext ctx = invoker.getInvocationContext();
ctx.getOptionOverrides().setCacheModeLocal(true);
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -32,17 +32,13 @@
/* parameters*/
private Map data;
- boolean createUndoOps;
- private boolean eraseContents;
private Map oldData;
- public PutDataMapCommand(GlobalTransaction globalTransaction, Fqn fqn, Map data, boolean createUndoOps, boolean eraseContents)
+ public PutDataMapCommand(GlobalTransaction globalTransaction, Fqn fqn, Map data)
{
this.globalTransaction = globalTransaction;
this.fqn = fqn;
this.data = data;
- this.createUndoOps = createUndoOps;
- this.eraseContents = eraseContents;
}
public PutDataMapCommand()
@@ -50,17 +46,13 @@
}
/**
- * Adds the provided data map to the data map in the node referenced by the specified Fqn, optionally erasing the node's
- * data first (if {@link #isEraseContents()} is <tt>true</tt>).
- *
- * @param ctx invocation context
- * @return null
+ * Adds the provided data map to the data map in the node referenced by the specified Fqn.
*/
public Object perform(InvocationContext ctx)
{
if (trace)
{
- log.trace("perform(" + globalTransaction + ", \"" + fqn + "\", " + data + " undo=" + createUndoOps + " erase=" + eraseContents + ")");
+ log.trace("perform(" + globalTransaction + ", \"" + fqn + "\", " + data + ")");
}
NodeSPI nodeSPI = dataContainer.peekStrict(globalTransaction, fqn, false);
Map existingData = nodeSPI.getDataDirect();
@@ -70,8 +62,6 @@
}
notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, oldData == null ? Collections.emptyMap() : oldData, ctx);
- if (eraseContents) nodeSPI.clearDataDirect();
-
nodeSPI.putAllDirect(data);
notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_MAP, nodeSPI.getDataDirect(), ctx);
return null;
@@ -98,16 +88,6 @@
return data;
}
- public boolean isEraseContents()
- {
- return eraseContents;
- }
-
- public boolean isCreateUndoOps()
- {
- return createUndoOps;
- }
-
public void setData(Map data)
{
this.data = data;
@@ -117,11 +97,10 @@
{
if (isVersioned())
{
- return eraseContents ? ERASE_VERSIONED_METHOD_ID : VERSIONED_METHOD_ID;
- }
- else
+ return VERSIONED_METHOD_ID;
+ } else
{
- return eraseContents ? ERASE_METHOD_ID : METHOD_ID;
+ return METHOD_ID;
}
}
@@ -129,9 +108,9 @@
public Object[] getParameters()
{
if (isVersioned())
- return new Object[]{globalTransaction, fqn, data, createUndoOps, dataVersion};
+ return new Object[]{globalTransaction, fqn, data, false, dataVersion};
else
- return new Object[]{globalTransaction, fqn, data, createUndoOps};
+ return new Object[]{globalTransaction, fqn, data, false};
}
@Override
@@ -140,8 +119,6 @@
globalTransaction = (GlobalTransaction) args[0];
fqn = (Fqn) args[1];
data = (Map) args[2];
- createUndoOps = (Boolean) args[3];
- eraseContents = commandId == ERASE_METHOD_ID;
if (isVersionedId(commandId)) dataVersion = (DataVersion) args[4];
}
@@ -157,11 +134,7 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
-
PutDataMapCommand that = (PutDataMapCommand) o;
-
- if (createUndoOps != that.createUndoOps) return false;
- if (eraseContents != that.eraseContents) return false;
if (data != null ? !data.equals(that.data) : that.data != null) return false;
if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
return false;
@@ -175,8 +148,6 @@
int result = super.hashCode();
result = 31 * result + (globalTransaction != null ? globalTransaction.hashCode() : 0);
result = 31 * result + (data != null ? data.hashCode() : 0);
- result = 31 * result + (createUndoOps ? 1 : 0);
- result = 31 * result + (eraseContents ? 1 : 0);
return result;
}
@@ -185,8 +156,6 @@
{
return "PutDataMapCommand{" +
"fqn=" + fqn +
- ", eraseContents=" + eraseContents +
- ", createUndoOps=" + createUndoOps +
", dataVersion=" + dataVersion +
", data=" + data +
", globalTransaction=" + globalTransaction +
@@ -197,9 +166,4 @@
{
return oldData;
}
-
- void setEraseContents(boolean eraseContents)
- {
- this.eraseContents = eraseContents;
- }
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutForExternalReadCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutForExternalReadCommand.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutForExternalReadCommand.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -16,9 +16,9 @@
public static final int METHOD_ID = 45;
public static final int VERSIONED_METHOD_ID = 46;
- public PutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value, boolean createUndoOps)
+ public PutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
{
- super(gtx, fqn, key, value, createUndoOps);
+ super(gtx, fqn, key, value);
}
public PutForExternalReadCommand()
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -31,16 +31,14 @@
/* parametres */
protected Object key;
protected Object value;
- protected boolean createUndoOps;
protected Object oldValue;
- public PutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value, boolean createUndoOps)
+ public PutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
{
this.globalTransaction = gtx;
this.fqn = fqn;
this.key = key;
this.value = value;
- this.createUndoOps = createUndoOps;
}
public PutKeyValueCommand()
@@ -98,11 +96,6 @@
return value;
}
- public boolean isCreateUndoOps()
- {
- return createUndoOps;
- }
-
public void setKey(Object key)
{
this.key = key;
@@ -129,9 +122,9 @@
public Object[] getParameters()
{
if (isVersioned())
- return new Object[]{globalTransaction, fqn, key, value, createUndoOps, dataVersion};
+ return new Object[]{globalTransaction, fqn, key, value, false, dataVersion};
else
- return new Object[]{globalTransaction, fqn, key, value, createUndoOps};
+ return new Object[]{globalTransaction, fqn, key, value, false};
}
@Override
@@ -141,7 +134,6 @@
fqn = (Fqn) args[1];
key = args[2];
value = args[3];
- createUndoOps = (Boolean) args[4];
if (isVersionedId(commandId)) dataVersion = (DataVersion) args[5];
}
@@ -154,7 +146,6 @@
PutKeyValueCommand that = (PutKeyValueCommand) o;
- if (createUndoOps != that.createUndoOps) return false;
if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
return false;
if (key != null ? !key.equals(that.key) : that.key != null) return false;
@@ -170,7 +161,6 @@
result = 31 * result + (globalTransaction != null ? globalTransaction.hashCode() : 0);
result = 31 * result + (key != null ? key.hashCode() : 0);
result = 31 * result + (value != null ? value.hashCode() : 0);
- result = 31 * result + (createUndoOps ? 1 : 0);
return result;
}
@@ -189,7 +179,6 @@
", globalTransaction=" + globalTransaction +
", key=" + key +
", value=" + value +
- ", createUndoOps=" + createUndoOps +
", oldValue=" + oldValue +
'}';
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -5,6 +5,7 @@
import org.jboss.cache.Fqn;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.NodeSPI;
+import org.jboss.cache.NodeNotExistsException;
import org.jboss.cache.commands.Visitor;
import org.jboss.cache.notifications.event.NodeModifiedEvent;
import org.jboss.cache.optimistic.DataVersion;
@@ -71,8 +72,12 @@
public void rollback()
{
- NodeSPI targetNode = dataContainer.peekStrict(globalTransaction, fqn, true);
- targetNode.putDirect(key, oldValue);
+ NodeSPI targetNode = dataContainer.peek(fqn, false, true);
+ if (targetNode == null) throw new NodeNotExistsException("No such node: " + fqn);
+ if (oldValue != null)
+ {
+ targetNode.putDirect(key, oldValue);
+ }
}
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -26,20 +26,15 @@
private static boolean trace = log.isTraceEnabled();
/*parameters*/
- private boolean createUndoOps;
- private boolean skipSendingNodeEvents;
- private boolean eviction;
- private Fqn parentFqn;
- private NodeSPI targetNode;
- private Map originalData;
+ private boolean skipSendingNodeEvents = false;
+ protected Fqn parentFqn;
+ protected NodeSPI targetNode;
+ protected Map originalData;
- public RemoveNodeCommand(GlobalTransaction globalTransaction, Fqn fqn, boolean createUndoOps, boolean skipSendingNodeEvents, boolean eviction)
+ public RemoveNodeCommand(GlobalTransaction globalTransaction, Fqn fqn)
{
this.globalTransaction = globalTransaction;
this.fqn = fqn;
- this.createUndoOps = createUndoOps;
- this.skipSendingNodeEvents = skipSendingNodeEvents;
- this.eviction = eviction;
}
public RemoveNodeCommand()
@@ -48,16 +43,10 @@
/**
* Removes the node referenced by the specified Fqn.
- *
- * @param ctx invocation context
- * @return true if the node was found and removed, false otherwise.
*/
public Object perform(InvocationContext ctx)
{
- NodeSPI parentNode;
- if (trace)
- log.trace("perform(" + globalTransaction + ", \"" + fqn + "\", undo=" + createUndoOps + ")");
-
+ if (trace) log.trace("perform(" + globalTransaction + ", \"" + fqn + ")");
// Find the node. This will add the temporarily created parent nodes to the TX's node list if globalTransaction != null)
targetNode = dataContainer.peekVersioned(fqn, dataVersion, true);
if (targetNode == null)
@@ -65,72 +54,43 @@
if (trace) log.trace("node " + fqn + " not found");
return false;
}
+ notifyBeforeRemove(targetNode, ctx);
- notifyBeforeEviction(targetNode, ctx);
+ NodeSPI parentNode = targetNode.getParent();
+ boolean found = targetNode.isValid() && !targetNode.isDeleted();
+ targetNode.markAsDeleted(true, true);
- parentNode = targetNode.getParent();
- boolean found;
-
- // remove subtree from parent
- if (eviction)
+ if (globalTransaction != null && found)
{
- // if there is no parent node and the fqn is root, found == true otherwise found == false.
- found = targetNode.isValid() && parentNode == null ? fqn.isRoot() : parentNode.removeChildDirect(targetNode.getFqn().getLastElement());
+ prepareForRollback(parentNode);
}
- else
- {
- found = targetNode.isValid() && !targetNode.isDeleted();
- targetNode.markAsDeleted(true, true);
- }
+ notifyAfterRemove(ctx);
+ return found;
+ }
- if (eviction && parentNode != null)
+ private void prepareForRollback(NodeSPI parentNode)
+ {
+ parentFqn = parentNode.getFqn();
+ Map targetData = targetNode.getDataDirect();
+ if (!targetData.isEmpty())
{
- parentNode.setChildrenLoaded(false);
+ originalData = new HashMap(targetNode.getDataDirect());
}
-
- // create a compensating method call (reverting the effect of
- // this modification) and put it into the TX's undo list.
- if (globalTransaction != null && createUndoOps && !eviction && found)
- {
- parentFqn = parentNode.getFqn();
- Map targetData = targetNode.getDataDirect();
- if (!targetData.isEmpty())
- {
- originalData = new HashMap(targetNode.getDataDirect());
- }
- }
-
- notifyAfterEviction(ctx);
- return found;
}
- private void notifyAfterEviction(InvocationContext ctx)
+ private void notifyBeforeRemove(NodeSPI n, InvocationContext ctx)
{
if (!skipSendingNodeEvents)
{
- if (eviction)
- {
- notifier.notifyNodeEvicted(fqn, false, ctx);
- }
- else
- {
- notifier.notifyNodeRemoved(fqn, false, null, ctx);
- }
+ notifier.notifyNodeRemoved(fqn, true, n.getDataDirect(), ctx);
}
}
- private void notifyBeforeEviction(NodeSPI n, InvocationContext ctx)
+ private void notifyAfterRemove(InvocationContext ctx)
{
if (!skipSendingNodeEvents)
{
- if (eviction)
- {
- notifier.notifyNodeEvicted(fqn, true, ctx);
- }
- else
- {
- notifier.notifyNodeRemoved(fqn, true, n.getDataDirect(), ctx);
- }
+ notifier.notifyNodeRemoved(fqn, false, null, ctx);
}
}
@@ -173,16 +133,6 @@
return skipSendingNodeEvents;
}
- public boolean isCreateUndoOps()
- {
- return createUndoOps;
- }
-
- public boolean isEviction()
- {
- return eviction;
- }
-
public int getCommandId()
{
return isVersioned() ? VERSIONED_METHOD_ID : METHOD_ID;
@@ -192,9 +142,9 @@
public Object[] getParameters()
{
if (isVersioned())
- return new Object[]{globalTransaction, fqn, createUndoOps, skipSendingNodeEvents, dataVersion};
+ return new Object[]{globalTransaction, fqn, true, skipSendingNodeEvents, dataVersion};
else
- return new Object[]{globalTransaction, fqn, createUndoOps, skipSendingNodeEvents};
+ return new Object[]{globalTransaction, fqn, true, skipSendingNodeEvents};
}
@Override
@@ -202,7 +152,6 @@
{
globalTransaction = (GlobalTransaction) args[0];
fqn = (Fqn) args[1];
- createUndoOps = (Boolean) args[2];
skipSendingNodeEvents = (Boolean) args[3];
if (isVersionedId(commandId)) dataVersion = (DataVersion) args[4];
}
@@ -216,8 +165,6 @@
RemoveNodeCommand that = (RemoveNodeCommand) o;
- if (createUndoOps != that.createUndoOps) return false;
- if (eviction != that.eviction) return false;
if (skipSendingNodeEvents != that.skipSendingNodeEvents) return false;
if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
return false;
@@ -230,9 +177,7 @@
{
int result = super.hashCode();
result = 31 * result + (globalTransaction != null ? globalTransaction.hashCode() : 0);
- result = 31 * result + (createUndoOps ? 1 : 0);
result = 31 * result + (skipSendingNodeEvents ? 1 : 0);
- result = 31 * result + (eviction ? 1 : 0);
return result;
}
@@ -254,9 +199,7 @@
"fqn=" + fqn +
", dataVersion=" + dataVersion +
", globalTransaction=" + globalTransaction +
- ", createUndoOps=" + createUndoOps +
", skipSendingNodeEvents=" + skipSendingNodeEvents +
- ", eviction=" + eviction +
", parentFqn=" + parentFqn +
", targetNode=" + targetNode +
'}';
Modified: core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -17,12 +17,7 @@
import org.jboss.cache.commands.read.GetKeysCommand;
import org.jboss.cache.commands.read.GetNodeCommand;
import org.jboss.cache.commands.read.GravitateDataCommand;
-import org.jboss.cache.commands.remote.AnnounceBuddyPoolNameCommand;
-import org.jboss.cache.commands.remote.AssignToBuddyGroupCommand;
-import org.jboss.cache.commands.remote.ClusteredGetCommand;
-import org.jboss.cache.commands.remote.DataGravitationCleanupCommand;
-import org.jboss.cache.commands.remote.RemoveFromBuddyGroupCommand;
-import org.jboss.cache.commands.remote.ReplicateCommand;
+import org.jboss.cache.commands.remote.*;
import org.jboss.cache.commands.tx.CommitCommand;
import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
import org.jboss.cache.commands.tx.PrepareCommand;
@@ -87,23 +82,23 @@
this.txManager = txManager;
}
- public PutDataMapCommand buildPutDataMapCommand(GlobalTransaction gtx, Fqn fqn, Map data, boolean createUndoOps, boolean eraseContents)
+ public PutDataMapCommand buildPutDataMapCommand(GlobalTransaction gtx, Fqn fqn, Map data)
{
- PutDataMapCommand cmd = new PutDataMapCommand(gtx, fqn, data, createUndoOps, eraseContents);
+ PutDataMapCommand cmd = new PutDataMapCommand(gtx, fqn, data);
cmd.initialize(notifier, dataContainer);
return cmd;
}
- public PutKeyValueCommand buildPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value, boolean createUndoOps)
+ public PutKeyValueCommand buildPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
{
- PutKeyValueCommand command = new PutKeyValueCommand(gtx, fqn, key, value, createUndoOps);
+ PutKeyValueCommand command = new PutKeyValueCommand(gtx, fqn, key, value);
command.initialize(notifier, dataContainer);
return command;
}
- public PutForExternalReadCommand buildPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value, boolean createUndoOps)
+ public PutForExternalReadCommand buildPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
{
- PutForExternalReadCommand command = new PutForExternalReadCommand(gtx, fqn, key, value, createUndoOps);
+ PutForExternalReadCommand command = new PutForExternalReadCommand(gtx, fqn, key, value);
command.initialize(notifier, dataContainer);
return command;
}
@@ -151,9 +146,9 @@
return command;
}
- public RemoveNodeCommand buildRemoveNodeCommand(GlobalTransaction gtx, Fqn fqn, boolean eviction, boolean skipSendingNodeEvents, boolean createUndoOps)
+ public RemoveNodeCommand buildRemoveNodeCommand(GlobalTransaction gtx, Fqn fqn)
{
- RemoveNodeCommand command = new RemoveNodeCommand(gtx, fqn, createUndoOps, skipSendingNodeEvents, eviction);
+ RemoveNodeCommand command = new RemoveNodeCommand(gtx, fqn);
command.initialize(notifier, dataContainer);
return command;
}
@@ -180,8 +175,7 @@
command.initialize(txManager);
command.initialize(cacheSpi, dataContainer, notifier);
return command;
- }
- else
+ } else
{
InvalidateCommand command = new InvalidateCommand(fqn);
command.initialize(cacheSpi, dataContainer, notifier);
@@ -460,8 +454,7 @@
returnValue.initialize(txManager);
returnValue.initialize(cacheSpi, dataContainer, notifier);
command = returnValue;
- }
- else
+ } else
{
InvalidateCommand returnValue = new InvalidateCommand();
returnValue.initialize(cacheSpi, dataContainer, notifier);
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -246,21 +246,11 @@
{
return returnValue;
}
- if (command.isEraseContents())
- {
- loader.removeData(command.getFqn());
- // if we are erasing all the data then consider this node loaded
- NodeSPI n = dataContainer.peek(command.getFqn(), false, false);
- n.setDataLoaded(true);
- return returnValue;
- }
- else
- {
- loader.put(command.getFqn(), command.getData());
- if (getStatisticsEnabled()) cacheStores++;
- return returnValue;
- }
+ loader.put(command.getFqn(), command.getData());
+ if (getStatisticsEnabled()) cacheStores++;
+
+ return returnValue;
}
@Override
@@ -388,14 +378,7 @@
public Object visitPutDataMapCommand(InvocationContext ctx, PutDataMapCommand command) throws Throwable
{
if (generateStatistics) putCount++;
- if (command.isEraseContents())
- {
- modifications.add(new Modification(Modification.ModificationType.PUT_DATA_ERASE, command.getFqn(), command.getData()));
- }
- else
- {
- modifications.add(new Modification(Modification.ModificationType.PUT_DATA, command.getFqn(), command.getData()));
- }
+ modifications.add(new Modification(Modification.ModificationType.PUT_DATA, command.getFqn(), command.getData()));
affectedFqns.add(command.getFqn());
return null;
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -116,7 +116,7 @@
size = command.getData().size();
}
EvictedEventNode event = new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, size);
- event.setResetElementCount(command.isEraseContents());
+ event.setResetElementCount(false);
registerEvictionEventToRegionManager(event, r);
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -280,7 +280,7 @@
@Override
public Object visitPutDataMapCommand(InvocationContext ctx, PutDataMapCommand command) throws Throwable
{
- VersionedDataCommand clone = commandsFactory.buildPutDataMapCommand(null, command.getFqn(), command.getData(), command.isCreateUndoOps(), command.isEraseContents());
+ VersionedDataCommand clone = commandsFactory.buildPutDataMapCommand(null, command.getFqn(), command.getData());
setDataVersion(clone, command.getFqn());
return null;
}
@@ -288,7 +288,7 @@
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable
{
- VersionedDataCommand clone = commandsFactory.buildPutKeyValueCommand(null, command.getFqn(), command.getKey(), command.getValue(), command.isCreateUndoOps());
+ VersionedDataCommand clone = commandsFactory.buildPutKeyValueCommand(null, command.getFqn(), command.getKey(), command.getValue());
setDataVersion(clone, command.getFqn());
return null;
}
@@ -296,7 +296,7 @@
@Override
public Object visitPutForExternalReadCommand(InvocationContext ctx, PutForExternalReadCommand command) throws Throwable
{
- VersionedDataCommand clone = commandsFactory.buildPutForExternalReadCommand(null, command.getFqn(), command.getKey(), command.getValue(), command.isCreateUndoOps());
+ VersionedDataCommand clone = commandsFactory.buildPutForExternalReadCommand(null, command.getFqn(), command.getKey(), command.getValue());
setDataVersion(clone, command.getFqn());
return null;
}
@@ -304,8 +304,7 @@
@Override
public Object visitRemoveNodeCommand(InvocationContext ctx, RemoveNodeCommand command) throws Throwable
{
- VersionedDataCommand clone = commandsFactory.buildRemoveNodeCommand(command.getGlobalTransaction(), command.getFqn(), command.isEviction(),
- command.isSkipSendingNodeEvents(), command.isCreateUndoOps());
+ VersionedDataCommand clone = commandsFactory.buildRemoveNodeCommand(command.getGlobalTransaction(), command.getFqn());
setDataVersion(clone, command.getFqn());
return null;
}
Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -390,7 +390,7 @@
InvocationContext ctx = invocationContextContainer.get();
cacheStatusCheck(ctx);
GlobalTransaction tx = transactionTable.getCurrentTransaction();
- RemoveNodeCommand command = commandsFactory.buildRemoveNodeCommand(tx, fqn, false, false, true);
+ RemoveNodeCommand command = commandsFactory.buildRemoveNodeCommand(tx, fqn);
Object retval = invoker.invoke(ctx, command);
return retval != null && (Boolean) retval;
}
@@ -432,7 +432,7 @@
{
InvocationContext ctx = invocationContextContainer.get();
cacheStatusCheck(ctx);
- PutDataMapCommand command = commandsFactory.buildPutDataMapCommand(null, fqn, data, true, false);
+ PutDataMapCommand command = commandsFactory.buildPutDataMapCommand(null, fqn, data);
invoker.invoke(ctx, command);
}
@@ -450,7 +450,7 @@
{
getInvocationContext().getOptionOverrides().setFailSilently(true);
getInvocationContext().getOptionOverrides().setForceAsynchronous(true);
- PutForExternalReadCommand command = commandsFactory.buildPutForExternalReadCommand(null, fqn, key, value, false);
+ PutForExternalReadCommand command = commandsFactory.buildPutForExternalReadCommand(null, fqn, key, value);
invoker.invoke(ctx, command);
}
else
@@ -465,7 +465,7 @@
InvocationContext ctx = invocationContextContainer.get();
cacheStatusCheck(ctx);
GlobalTransaction tx = transactionTable.getCurrentTransaction();
- PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(tx, fqn, key, value, false);
+ PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(tx, fqn, key, value);
return (V) invoker.invoke(ctx, command);
}
Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -266,7 +266,7 @@
childNode.markAsDeleted(false);
//if we'll rollback the tx data should be added to the node again
Map oldData = new HashMap(childNode.getDataDirect());
- PutDataMapCommand command = commandsFactory.buildPutDataMapCommand(ctx.getGlobalTransaction(), fqn, oldData, false, false);
+ PutDataMapCommand command = commandsFactory.buildPutDataMapCommand(ctx.getGlobalTransaction(), fqn, oldData);
// txTable.get(gtx).addUndoOperation(command); --- now need to make sure this is added to the normal mods list instead
entry.addModification(command);
//we're prepared for rollback, now reset the node
Modified: core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -139,7 +139,7 @@
{
Fqn fqn1 = Fqn.fromString("/hello/world");
- PutKeyValueCommand call1 = new PutKeyValueCommand(null, fqn1, "key", "value", false);
+ PutKeyValueCommand call1 = new PutKeyValueCommand(null, fqn1, "key", "value");
ReplicateCommand call2 = new ReplicateCommand(call1);
BuddyManager bm = createBasicBuddyManager();
@@ -157,7 +157,7 @@
{
Fqn fqn1 = Fqn.ROOT;
- ReplicableCommand call1 = new PutKeyValueCommand(null, fqn1, "key", "value", false);
+ ReplicableCommand call1 = new PutKeyValueCommand(null, fqn1, "key", "value");
ReplicateCommand call2 = new ReplicateCommand(call1);
BuddyManager bm = createBasicBuddyManager();
@@ -177,10 +177,10 @@
Fqn fqn3 = Fqn.fromString("/hello/again");
Fqn fqn4 = Fqn.fromString("/buddy/replication");
- PutKeyValueCommand call1 = new PutKeyValueCommand(null, fqn1, "key", "value", false);
- PutKeyValueCommand call2 = new PutKeyValueCommand(null, fqn2, "key", "value", false);
- PutKeyValueCommand call3 = new PutKeyValueCommand(null, fqn3, "key", "value", false);
- PutKeyValueCommand call4 = new PutKeyValueCommand(null, fqn4, "key", "value", false);
+ PutKeyValueCommand call1 = new PutKeyValueCommand(null, fqn1, "key", "value");
+ PutKeyValueCommand call2 = new PutKeyValueCommand(null, fqn2, "key", "value");
+ PutKeyValueCommand call3 = new PutKeyValueCommand(null, fqn3, "key", "value");
+ PutKeyValueCommand call4 = new PutKeyValueCommand(null, fqn4, "key", "value");
List<ReplicableCommand> list = new ArrayList<ReplicableCommand>();
list.add(call1);
list.add(call2);
Modified: core/trunk/src/test/java/org/jboss/cache/commands/write/PutDataMapCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/PutDataMapCommandTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/PutDataMapCommandTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -2,20 +2,17 @@
import static org.easymock.EasyMock.*;
import org.easymock.IMocksControl;
-import org.jboss.cache.commands.read.AbstractDataCommandTest;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.notifications.Notifier;
import org.jboss.cache.notifications.event.NodeModifiedEvent;
import org.jboss.cache.Fqn;
import org.jboss.cache.DataContainer;
-import org.jboss.cache.NodeSPI;
import org.jboss.cache.mock.NodeSpiMock;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import java.util.Map;
import java.util.HashMap;
-import java.util.Collections;
/**
* Tester class for {@link PutDataMapCommand}
@@ -42,7 +39,7 @@
{
gtx = new GlobalTransaction();
dataMap = new HashMap();
- command = new PutDataMapCommand(gtx, testFqn, dataMap, true, false);
+ command = new PutDataMapCommand(gtx, testFqn, dataMap);
control = createStrictControl();
notifier = control.createMock(Notifier.class);
container = control.createMock(DataContainer.class);
@@ -66,33 +63,8 @@
assert command.getOldData().get("k").equals("v");
control.verify();
}
- public void testAddDataWithErase()
- {
- command.setEraseContents(true);
- expect(container.peekStrict(gtx, testFqn, false)).andReturn(node);
- dataMap.put("k2", "v2");
- Map expected = new HashMap(dataMap);
- notifier.notifyNodeModified(testFqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, node.getData(), null);
- notifier.notifyNodeModified(testFqn, false, NodeModifiedEvent.ModificationType.PUT_MAP, expected, null);
+
- control.replay();
- assert null == command.perform(null) : "null result is always expected";
- assert command.getOldData().size() == 1;
- assert command.getOldData().get("k").equals("v");
- assert node.getData().size() == 1;
- assert node.getData().get("k2").equals("v2");
- control.verify();
- control.reset();
-
- //check rollback now
- expect(container.peek(testFqn, false, true)).andReturn(node);
- control.replay();
- command.rollback();
- assert node.getData().size() == 1;
- assert node.getData().containsKey("k");
- control.verify();
- }
-
public void testRollbackNonexistentNode()
{
expect(container.peek(testFqn, false, true)).andReturn(null);
Modified: core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -7,7 +7,6 @@
import java.util.Map;
import java.util.HashMap;
-import java.util.Collections;
/**
* tester class for {@link PutKeyValueCommand}.
@@ -22,7 +21,7 @@
public AbstractVersionedDataCommand moreSetUp()
{
- command = new PutForExternalReadCommand(globalTransaction, fqn, "k", "v", true);
+ command = new PutForExternalReadCommand(globalTransaction, fqn, "k", "v");
return command;
}
@@ -63,7 +62,6 @@
assert nodes.adfNode.getData().size() == 1;
assert "existingValue".equals(nodes.adfNode.getData().get("existingKey"));
control.verify();
-
}
public void testOverWriteData()
Modified: core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveKeyCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveKeyCommandTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveKeyCommandTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -47,7 +47,17 @@
notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
control.replay();
assert null == command.perform(ctx);
+ assert nodes.adfgNode.getData().size() == 1;
+ assert "newValue".equals(nodes.adfgNode.getData().get("newKey"));
control.verify();
+
+ control.reset();
+ expect(container.peek(fqn, false, true)).andReturn(nodes.adfgNode);
+ control.replay();
+ command.rollback();
+ assert nodes.adfgNode.getData().size() == 1;
+ assert "newValue".equals(nodes.adfgNode.getData().get("newKey"));
+ control.verify();
}
public void testRemoveExistentPair()
@@ -57,11 +67,18 @@
nodes.adfgNode.putAll(expected);
expect(container.peek(fqn, false, false)).andReturn(nodes.adfgNode);
notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
- expected = new HashMap();
- expected.put(key,null);
notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
control.replay();
- assert null == command.perform(ctx);
+ assert "newValue" == command.perform(ctx);
+ assert nodes.adfgNode.getData().get(key) == null;
control.verify();
+
+ control.reset();
+ expect(container.peek(fqn, false, true)).andReturn(nodes.adfgNode);
+ control.replay();
+ command.rollback();
+ assert nodes.adfgNode.getData().size() == 1;
+ assert "newValue".equals(nodes.adfgNode.getData().get(key));
+ control.verify();
}
}
Added: core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveNodeCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveNodeCommandTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveNodeCommandTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -0,0 +1,82 @@
+package org.jboss.cache.commands.write;
+
+import static org.easymock.EasyMock.*;
+import org.testng.annotations.Test;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+/**
+ * tester for {@link RemoveNodeCommand}.
+ *
+ * @author Mircea.Markus(a)jboss.com
+ * @since 2.2
+ */
+@Test(groups = "unit")
+public class RemoveNodeCommandTest extends AbstractVersionedDataCommandTest
+{
+ RemoveNodeCommand command;
+
+ public AbstractVersionedDataCommand moreSetUp()
+ {
+ command = new RemoveNodeCommand(globalTransaction, fqn);
+ command.setDataVersion(dataVersion);
+ return command;
+ }
+
+ public void testNonExistentNode()
+ {
+ expect(container.peekVersioned(fqn, dataVersion, true)).andReturn(null);
+ control.replay();
+ assert Boolean.FALSE == command.perform(ctx) : "nonexistent node was not remove; false expected";
+ }
+
+ public void testRemovalNoNotificationsValidNode()
+ {
+ //aditional setup
+ command.setSkipSendingNodeEvents(true); //no notification
+ nodes.adfNode.put("akey","avalue");
+ ctx.setGlobalTransaction(new GlobalTransaction());
+
+ //check perform
+ expect(container.peekVersioned(fqn, dataVersion, true)).andReturn(nodes.adfNode);
+ control.replay();
+ assert Boolean.TRUE == command.perform(ctx);
+ assert nodes.adfgNode.isDeleted();
+ assert nodes.adfhNode.isDeleted();
+ assert command.originalData != null;
+ control.verify();
+
+ //check rollback
+ control.reset();
+ nodes.adNode.removeChild("f");
+ expect(container.peek(nodes.ad)).andReturn(nodes.adNode);
+ control.replay();
+ command.rollback();
+ assert nodes.adNode.hasChild("f");
+ }
+ public void testRemovalNoNotificationsInvalidNode()
+ {
+ command.setSkipSendingNodeEvents(true); //no notification
+ nodes.adfNode.setValid(false, false); //invalid node
+
+ expect(container.peekVersioned(fqn, dataVersion, true)).andReturn(nodes.adfNode);
+ control.replay();
+ assert Boolean.FALSE == command.perform(ctx);
+ assert nodes.adfgNode.isDeleted();
+ assert nodes.adfhNode.isDeleted();
+ control.verify();
+ }
+
+ public void testRemovalWithNotificationsInvalidNode()
+ {
+ nodes.adfNode.setValid(false, false); //invalid node
+
+ expect(container.peekVersioned(fqn, dataVersion, true)).andReturn(nodes.adfNode);
+ notifier.notifyNodeRemoved(fqn, true, nodes.adfNode.getDataDirect(), ctx);
+ notifier.notifyNodeRemoved(fqn, false, null, ctx);
+ control.replay();
+ assert Boolean.FALSE == command.perform(ctx);
+ assert nodes.adfgNode.isDeleted();
+ assert nodes.adfhNode.isDeleted();
+ control.verify();
+ }
+}
Modified: core/trunk/src/test/java/org/jboss/cache/interceptors/EvictionInterceptorTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/interceptors/EvictionInterceptorTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/interceptors/EvictionInterceptorTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -303,7 +303,7 @@
// this region is node granularity
Fqn fqn = Fqn.fromString("/a/b/c");
- PutDataMapCommand putDataMapCommand = commandsFactory.buildPutDataMapCommand(null, fqn, data, false, false);
+ PutDataMapCommand putDataMapCommand = commandsFactory.buildPutDataMapCommand(null, fqn, data);
invoker.invoke(putDataMapCommand);
Region region = regionManager.getRegion(fqn.toString(), false);
@@ -324,7 +324,7 @@
for (int i = 0; i < 100; i++)
{
- PutKeyValueCommand pkvCommand = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, i, "value", false);
+ PutKeyValueCommand pkvCommand = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, i, "value");
invoker.invoke(pkvCommand);
assertEquals("value", cache.peek(fqn, false, false).getDirect(i));
@@ -341,7 +341,7 @@
assertNull(region.takeLastEventNode());
fqn = Fqn.fromString("/a/b");
- PutDataMapCommand putCommand = commandsFactory.buildPutDataMapCommand(null, fqn, data, false, false);
+ PutDataMapCommand putCommand = commandsFactory.buildPutDataMapCommand(null, fqn, data);
invoker.invoke(putCommand);
event = regionManager.getRegion(fqn.toString(), false).takeLastEventNode();
assertFalse(event.isResetElementCount());
@@ -360,7 +360,7 @@
assertEquals(i, node.getDirect(i));
}
- PutDataMapCommand putDataMap = commandsFactory.buildPutDataMapCommand(null, fqn, data, false, true);
+ PutDataMapCommand putDataMap = commandsFactory.buildPutDataMapCommand(null, fqn, data);
invoker.invoke(putDataMap);
event = regionManager.getRegion(fqn.toString(), false).takeLastEventNode();
assertEquals(NodeEventType.ADD_NODE_EVENT, event.getEventType());
@@ -389,7 +389,7 @@
Object key = "key";
Object value = "value";
- PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, key, value, false);
+ PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, key, value);
invoker.invoke(command);
assertEquals("value", cache.peek(fqn, false, false).getDirect(key));
EvictedEventNode event = region.takeLastEventNode();
@@ -399,7 +399,7 @@
assertEquals("value", cache.peek(fqn, false, false).getDirect(key));
assertNull(region.takeLastEventNode());
- command = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, key, value, false);
+ command = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, key, value);
invoker.invoke(command);
assertEquals("value", cache.peek(fqn, false, false).getDirect(key));
event = region.takeLastEventNode();
@@ -427,7 +427,7 @@
assertEquals(fqn, event.getFqn());
assertNull(region.takeLastEventNode());
- RemoveNodeCommand removeNodeCommand = commandsFactory.buildRemoveNodeCommand(null, fqn, false, false, false);
+ RemoveNodeCommand removeNodeCommand = commandsFactory.buildRemoveNodeCommand(null, fqn);
invoker.invoke(removeNodeCommand);
assertNull(cache.peek(fqn, false, false));
@@ -482,7 +482,7 @@
// this region is node granularity
Fqn fqn = Fqn.fromString("/a/b/c");
- PutDataMapCommand putDataCommand = commandsFactory.buildPutDataMapCommand(null, fqn, data, false, false);
+ PutDataMapCommand putDataCommand = commandsFactory.buildPutDataMapCommand(null, fqn, data);
invoker.invoke(putDataCommand);
Region region = regionManager.getRegion(fqn.toString(), false);
@@ -500,7 +500,7 @@
assertEquals(fqn, event.getFqn());
assertNull(region.takeLastEventNode());
- RemoveNodeCommand removeNodeCommand = commandsFactory.buildRemoveNodeCommand(null, fqn, false, false, false);
+ RemoveNodeCommand removeNodeCommand = commandsFactory.buildRemoveNodeCommand(null, fqn);
invoker.invoke(removeNodeCommand);
assertNull(cache.getNode(fqn));
event = region.takeLastEventNode();
@@ -510,7 +510,7 @@
Object key = "key";
Object value = "value";
- PutKeyValueCommand putKeyValueCommand = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, key, value, false);
+ PutKeyValueCommand putKeyValueCommand = commandsFactory.buildPutKeyValueCommand(null, (Fqn<?>) fqn, key, value);
invoker.invoke(putKeyValueCommand);
assertEquals("value", cache.peek(fqn, false, false).getDirect(key));
event = region.takeLastEventNode();
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/ActiveInactiveTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/ActiveInactiveTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/ActiveInactiveTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -152,7 +152,7 @@
public void testObjectFromByteBuffer() throws Exception
{
- PutKeyValueCommand put = new PutKeyValueCommand(null, A_B, "name", "Joe", false);
+ PutKeyValueCommand put = new PutKeyValueCommand(null, A_B, "name", "Joe");
ReplicateCommand replicate = new ReplicateCommand(put);
rman.setDefaultInactive(true);
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller210Test.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller210Test.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller210Test.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -29,7 +29,7 @@
Map map = createMap(size);
Fqn fqn = Fqn.fromString("/my/stuff");
String key = "key";
- PutKeyValueCommand putCommand = new PutKeyValueCommand(null, fqn, key, map, false);
+ PutKeyValueCommand putCommand = new PutKeyValueCommand(null, fqn, key, map);
ReplicateCommand replicateCommand = new ReplicateCommand(putCommand);
byte[] buf = marshaller.objectToByteBuffer(replicateCommand);
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -112,7 +112,7 @@
public void testMethodCall() throws Exception
{
Fqn fqn = Fqn.fromElements(3, false);
- ReplicableCommand cmd = new PutKeyValueCommand(null, fqn, "key", "value", false);
+ ReplicableCommand cmd = new PutKeyValueCommand(null, fqn, "key", "value");
byte[] asBytes = marshaller.objectToByteBuffer(cmd);
Object o2 = marshaller.objectFromByteBuffer(asBytes);
@@ -125,7 +125,7 @@
public void testNestedMethodCall() throws Exception
{
Fqn fqn = Fqn.fromElements(3, false);
- ReplicableCommand cmd = new PutKeyValueCommand(null, fqn, "key", "value", false);
+ ReplicableCommand cmd = new PutKeyValueCommand(null, fqn, "key", "value");
ReplicableCommand replicateCmd = new ReplicateCommand(cmd);
byte[] asBytes = marshaller.objectToByteBuffer(replicateCmd);
Object o2 = marshaller.objectFromByteBuffer(asBytes);
@@ -215,12 +215,12 @@
Fqn f = Fqn.fromElements("BlahBlah", 3, false);
String k = "key", v = "value";
- ReplicableCommand cmd = new PutKeyValueCommand(null, f, k, v, true);
+ ReplicableCommand cmd = new PutKeyValueCommand(null, f, k, v);
ReplicableCommand replCmd = new ReplicateCommand(cmd);
calls.add(replCmd);
- cmd = new PutKeyValueCommand(null, f, k, v, true);
+ cmd = new PutKeyValueCommand(null, f, k, v);
replCmd = new ReplicateCommand(cmd);
calls.add(replCmd);
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -36,11 +36,11 @@
byteStream = new ByteArrayOutputStream();
stream = new ObjectOutputStream(byteStream);
- command1 = new PutDataMapCommand(null, Fqn.ROOT, null, false, true);
+ command1 = new PutDataMapCommand(null, Fqn.ROOT, null);
list.clear();
list.add(command1);
- list.add(new PutDataMapCommand(null, Fqn.ROOT, null, false, true));
+ list.add(new PutDataMapCommand(null, Fqn.ROOT, null));
prepareComand = new PrepareCommand(null, list, null, true);
CacheMarshaller210 cm210 = new CacheMarshaller210();
Modified: core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java 2008-05-21 08:31:52 UTC (rev 5880)
+++ core/trunk/src/test/java/org/jboss/cache/mock/NodeSpiMock.java 2008-05-21 16:12:49 UTC (rev 5881)
@@ -100,7 +100,14 @@
public void markAsDeleted(boolean marker, boolean recursive)
{
- throw new UnsupportedOperationException();
+ this.isDeleted = marker;
+ if (recursive)
+ {
+ for (NodeSpiMock child : children.values())
+ {
+ child.markAsDeleted(marker, true);
+ }
+ }
}
public void addChild(Object nodeName, Node nodeToAdd)
16 years, 7 months