JBoss Cache SVN: r4731 - core/trunk/src/test/java/org/jboss/cache/lock/pessimistic.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2007-11-06 11:37:03 -0500 (Tue, 06 Nov 2007)
New Revision: 4731
Modified:
core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
Log:
JBCACHE-1165 - upped invocation count
Modified: core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java 2007-11-06 16:36:02 UTC (rev 4730)
+++ core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java 2007-11-06 16:37:03 UTC (rev 4731)
@@ -51,7 +51,7 @@
}
}
- @Test (invocationCount = 20)
+ @Test (invocationCount = 50)
public void testLock() throws Exception {
for (int x = 0; x < 2; x++) {
SeparateThread t = new SeparateThread(x);
17 years, 1 month
JBoss Cache SVN: r4730 - core/trunk/src/main/java/org/jboss/cache/interceptors.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2007-11-06 11:36:02 -0500 (Tue, 06 Nov 2007)
New Revision: 4730
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
Log:
Much better behaviour with JBCACHE-1165. Better logging, and added a null check
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2007-11-06 15:13:18 UTC (rev 4729)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2007-11-06 16:36:02 UTC (rev 4730)
@@ -315,12 +315,12 @@
}
boolean created = false;
- if (log.isTraceEnabled()) log.trace("Directly got child node " + child_name + ". Hash code is " + (child_node == null ? "null" : child_node.hashCode()));
+ if (log.isTraceEnabled()) log.trace("Directly got child node " + child_name);
if (child_node == null && createIfNotExists)
{
child_node = n.addChildDirect(new Fqn(child_name));
created = true;
- if (log.isTraceEnabled()) log.trace("Created child node " + child_name + ". Hash code is " + (child_node == null ? "null" : child_node.hashCode()));
+ if (log.isTraceEnabled()) log.trace("Child node was null, so created child node " + child_name);
}
if (child_node == null)
@@ -361,12 +361,15 @@
acquireNodeLock(child_node, owner, gtx, lockTypeRequired, timeout);
// make sure the lock we acquired isn't on a deleted node/is an orphan!!
- if (child_node != cache.peek(child_node.getFqn(), true))
+ NodeSPI repeek = cache.peek(child_node.getFqn(), true);
+ if (repeek != null && child_node != repeek)
{
+ 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).
child_node.getLock().release(owner);
// do the loop again, but don't assign child_node to n so that child_node is processed again.
+ i--;
continue;
}
17 years, 1 month
JBoss Cache SVN: r4729 - in core/trunk/src: test/java/org/jboss/cache/lock/pessimistic and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2007-11-06 10:13:18 -0500 (Tue, 06 Nov 2007)
New Revision: 4729
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
Log:
Much better behaviour with JBCACHE-1165. No more endless loops and lock acquisition timeouts when you have concurrent puts and removes.
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2007-11-06 03:36:23 UTC (rev 4728)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2007-11-06 15:13:18 UTC (rev 4729)
@@ -120,6 +120,7 @@
fqn = (Fqn) args[1];
lock_type = NodeLock.LockType.WRITE;
recursive = true;// remove node and *all* child nodes
+ createIfNotExists = true;
break;
case MethodDeclarations.putDataMethodLocal_id:
case MethodDeclarations.putDataEraseMethodLocal_id:
@@ -181,9 +182,15 @@
if (!locksAlreadyObtained)
{
long timeout = zeroLockTimeout ? 0 : getLockAcquisitionTimeout(ctx);
+ // 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");
lock(ctx, fqn, lock_type, recursive, createIfNotExists, timeout, isDeleteOperation, isEvictOperation, isRemoveDataOperation);
+ firstTry = false;
}
while (createIfNotExists && cache.peek(fqn, false) == null);// keep trying until we have the lock (fixes concurrent remove())
}
@@ -204,14 +211,6 @@
// to add the removedNodes map to CacheImpl
if (isDeleteOperation && ctx.getGlobalTransaction() == null)
{
- //cache.getRemovedNodesMap().remove(fqn);
- //cache.peek(fqn);
- // do a REAL remove here.
- NodeSPI n = cache.peek(fqn, true);
- if (n != null)
- {
- lockManager.getLock(n).releaseAll(Thread.currentThread());
- }
//CacheIml._move internally removes the source node. 'if clause' solve the scenario when a node is
// moved in the same place, i.e. it will be removed from the source - which is also destination - so it ends
// up being removed for good
@@ -219,9 +218,14 @@
{
((CacheImpl) cache).realRemove(fqn, true);
}
+ // do a REAL remove here.
+ NodeSPI n = cache.peek(fqn, true);
+ if (n != null)
+ {
+ lockManager.getLock(n).releaseAll(Thread.currentThread());
+ }
}
- else
- if (m.getMethodId() == MethodDeclarations.commitMethod_id || isOnePhaseCommitPrepareMehod(m) || m.getMethodId() == MethodDeclarations.rollbackMethod_id)
+ else if (m.getMethodId() == MethodDeclarations.commitMethod_id || isOnePhaseCommitPrepareMehod(m) || m.getMethodId() == MethodDeclarations.rollbackMethod_id)
{
cleanup(ctx.getGlobalTransaction());
}
@@ -311,10 +315,12 @@
}
boolean created = false;
+ if (log.isTraceEnabled()) log.trace("Directly got child node " + child_name + ". Hash code is " + (child_node == null ? "null" : child_node.hashCode()));
if (child_node == null && createIfNotExists)
{
child_node = n.addChildDirect(new Fqn(child_name));
created = true;
+ if (log.isTraceEnabled()) log.trace("Created child node " + child_name + ". Hash code is " + (child_node == null ? "null" : child_node.hashCode()));
}
if (child_node == null)
@@ -351,9 +357,19 @@
reverseRemove(child_node);
}
- // actually acquire the lock we need.
+ // actually acquire the lock we need. This method blocks.
acquireNodeLock(child_node, owner, gtx, lockTypeRequired, timeout);
+ // make sure the lock we acquired isn't on a deleted node/is an orphan!!
+ if (child_node != cache.peek(child_node.getFqn(), true))
+ {
+ // we have an orphan!! Lose the unnecessary lock and re-acquire the lock (and potentially recreate the node).
+ child_node.getLock().release(owner);
+
+ // do the loop again, but don't assign child_node to n so that child_node is processed again.
+ continue;
+ }
+
if (recursive && isTargetNode(i, treeNodeSize))
{
Set<NodeLock> acquired_locks = lockManager.acquireAll(child_node, owner, lock_type, timeout);
Modified: core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java 2007-11-06 03:36:23 UTC (rev 4728)
+++ core/trunk/src/test/java/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java 2007-11-06 15:13:18 UTC (rev 4729)
@@ -1,46 +1,58 @@
package org.jboss.cache.lock.pessimistic;
-import org.testng.annotations.Test;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.AfterMethod;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Cache;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Configuration;
import org.jboss.cache.lock.IsolationLevel;
-import org.jboss.cache.config.Configuration;
+import org.jboss.cache.misc.TestingUtil;
import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import javax.transaction.TransactionManager;
import java.util.ArrayList;
import java.util.List;
-import javax.transaction.TransactionManager;
-
-@Test(groups = {"functional"}, enabled = false) // Known issue - See JBCACHE-1164 and JBCACHE-1165
+@Test(groups = {"functional"}, enabled = true) // Known issue - See JBCACHE-1164 and JBCACHE-1165
public class ConcurrentPutRemoveTest
{
private TransactionManager tm;
private Cache cache;
+ private final Log log = LogFactory.getLog(ConcurrentPutRemoveTest.class);
+ private List<SeparateThread> threads;
+
+
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception {
cache = DefaultCacheFactory.getInstance().createCache(false);
cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
cache.getConfiguration().setIsolationLevel(IsolationLevel.READ_COMMITTED);
cache.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
- cache.getConfiguration().setLockAcquisitionTimeout(10000);
+ cache.getConfiguration().setLockAcquisitionTimeout(1000);
cache.start();
tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
- }
+ threads = new ArrayList<SeparateThread>();
+ }
@AfterMethod(alwaysRun = true)
public void tearDown() throws Exception
{
- cache.destroy();
- }
+ TestingUtil.killCaches(cache);
+ for (SeparateThread st : threads)
+ {
+ st.interrupt();
+ st.join();
+ }
+ }
+ @Test (invocationCount = 20)
public void testLock() throws Exception {
- List<SeparateThread> threads = new ArrayList<SeparateThread>();
for (int x = 0; x < 2; x++) {
SeparateThread t = new SeparateThread(x);
threads.add(t);
@@ -72,16 +84,16 @@
Thread.currentThread().setName("Thread:" + num);
try {
for (int x = 0; x < 1000; x++) {
- tm.begin();
- System.out.println("R" + Thread.currentThread().getName());
+ tm.begin();
+ log.warn("Before Remove ("+x+")");
//inside transaction
cache.removeNode(Fqn.fromString("/a"));
- System.out.println("AR" + Thread.currentThread().getName());
+ log.warn("After Remove ("+x+")");
tm.commit();
//outside transaction
- System.out.println("P" + Thread.currentThread().getName());
+ log.warn("Before Put ("+x+")");
cache.put(Fqn.fromString("/a/b/c/d"), "text"+x,"b");
- System.out.println("AP" + Thread.currentThread().getName());
+ log.warn("After Put ("+x+")");
}
} catch (Exception e) {
this.e = e;
17 years, 1 month
JBoss Cache SVN: r4728 - in core/trunk/src: main/java/org/jboss/cache/config and 4 other directories.
by jbosscache-commits@lists.jboss.org
Author: bstansberry(a)jboss.com
Date: 2007-11-05 22:36:23 -0500 (Mon, 05 Nov 2007)
New Revision: 4728
Added:
core/trunk/src/main/java/org/jboss/cache/CacheManager.java
core/trunk/src/main/java/org/jboss/cache/CacheManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/config/ConfigurationRegistry.java
core/trunk/src/main/java/org/jboss/cache/config/XmlParsingConfigurationRegistry.java
core/trunk/src/main/java/org/jboss/cache/factories/CacheConfigsXmlParser.java
core/trunk/src/test/java/org/jboss/cache/manager/
core/trunk/src/test/java/org/jboss/cache/manager/CacheManagerTest.java
Removed:
core/trunk/src/main/java/org/jboss/cache/registry/CacheConfigsXmlParser.java
core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistry.java
core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistryImpl.java
core/trunk/src/main/java/org/jboss/cache/registry/ConfigurationRegistry.java
core/trunk/src/main/java/org/jboss/cache/registry/XmlParsingConfigurationRegistry.java
core/trunk/src/test/java/org/jboss/cache/manager/CacheRegistryTest.java
core/trunk/src/test/java/org/jboss/cache/registry/
Log:
[JBCACHE-1156] Repackage
Added: core/trunk/src/main/java/org/jboss/cache/CacheManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/CacheManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/CacheManager.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache;
+
+import java.util.Set;
+
+import org.jboss.cache.config.Configuration;
+import org.jgroups.ChannelFactory;
+
+/**
+ * Factory and registry for JBoss Cache instances configured using
+ * named configurations.
+ *
+ * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public interface CacheManager {
+
+ /**
+ * Gets the names of all the configurations of which this object
+ * is aware.
+ *
+ * @return a set of names. Will not be <code>null</code>.
+ */
+ Set<String> getConfigurationNames();
+
+ /**
+ * Gets the name of all caches that are registered, i.e. that can be
+ * by a call to {@link #getCache(String, boolean) getCache(name, false)}.
+ *
+ * @return a set of names. Will not be <code>null</code>.
+ */
+ Set<String> getCacheNames();
+
+ /**
+ * Gets the JGroups <code>ChannelFactory</code> that will be injected
+ * into any {@link Configuration} that has a
+ * {@link Configuration#getMultiplexerStack() multiplexer stack}
+ * configured.
+ *
+ * @return
+ */
+ ChannelFactory getChannelFactory();
+
+ /**
+ * Get a cache configured according to the given configuration name,
+ * optionally instantiating the cache if it hasn't already been
+ * instantiated.
+ * <p>
+ * The caller is free to invoke the {@link Cache#create()} and
+ * {@link Cache#start()} lifecycle methods on the returned cache, but
+ * the @link Cache#stop()} and {@link Cache#destroy()} methods should not
+ * be invoked, since it is quite possible other users are still using the
+ * cache. Use {@link #releaseCache(String)} to notify this
+ * registry that the caller is no longer using a cache; let the registry
+ * control stopping and destroying the cache.
+ * </p>
+ * <p>
+ * If invoking this method leads to the instantiation of the cache,
+ * <code>create()</code> and <code>start()</code> will not be invoked
+ * on the cache before it is returned.
+ * </p>
+ *
+ * @param configName the name of the configuration
+ * @param create should the cache be instantiated if it
+ * hasn't already been?
+ * @return the cache, or <code>null</code> if
+ * <code>create</code> is false and the cache hasn't
+ * been created previously.
+ *
+ * @throws IllegalArgumentException if this object is unaware of
+ * <code>configName</code>; i.e. the set
+ * returned from {@link #getConfigurationNames()}
+ * does not include <code>configName</code>
+ * @throws Exception if there is a problem instantiating the cache
+ */
+ Cache<Object, Object> getCache(String configName, boolean create) throws Exception;
+
+ /**
+ * Notifies the registry that the caller is no longer using the given
+ * cache. The registry may perform cleanup operations, such as
+ * stopping and destroying the cache.
+ *
+ * @param configName
+ */
+ void releaseCache(String configName);
+
+}
\ No newline at end of file
Property changes on: core/trunk/src/main/java/org/jboss/cache/CacheManager.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/src/main/java/org/jboss/cache/CacheManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/CacheManagerImpl.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/CacheManagerImpl.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details. You should have received a
+ * copy of the GNU Lesser General Public License, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Brian Stansberry
+ */
+
+package org.jboss.cache;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationRegistry;
+import org.jboss.cache.config.XmlParsingConfigurationRegistry;
+import org.jgroups.ChannelFactory;
+
+/**
+ * Basic implementation of {@link CacheManager}.
+ *
+ * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public class CacheManagerImpl implements CacheManager
+{
+ private ConfigurationRegistry configRegistry;
+
+ private boolean configRegistryInjected;
+
+ private Map<String, Cache<Object, Object>> caches = new HashMap<String, Cache<Object, Object>>();
+
+ private Map<String, Integer> checkouts = new HashMap<String, Integer>();
+
+ private ChannelFactory channelFactory;
+
+ private boolean started;
+
+ /**
+ * Create a new CacheRegistryImpl.
+ */
+ public CacheManagerImpl()
+ {
+ }
+
+ /**
+ * Create a new CacheRegistryImpl using the provided ConfigurationRegistry
+ * and ChannelFactory.
+ */
+ public CacheManagerImpl(ConfigurationRegistry configRegistry, ChannelFactory factory)
+ {
+ this.configRegistry = configRegistry;
+ this.configRegistryInjected = true;
+ this.channelFactory = factory;
+ }
+
+ /**
+ * Create a new CacheRegistryImpl using the provided ChannelFactory and
+ * using the provided file name to create an
+ * {@link XmlParsingConfigurationRegistry}.
+ */
+ public CacheManagerImpl(String configFileName, ChannelFactory factory)
+ {
+ configRegistry = new XmlParsingConfigurationRegistry(configFileName);
+ this.channelFactory = factory;
+ }
+
+ // ---------------------------------------------------------- CacheRegistry
+
+ public ChannelFactory getChannelFactory()
+ {
+ return channelFactory;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Set<String> getConfigurationNames()
+ {
+ synchronized (caches)
+ {
+ Set<String> configNames = configRegistry == null ? new HashSet<String>()
+ : configRegistry.getConfigurationNames();
+ configNames.addAll(getCacheNames());
+ return configNames;
+ }
+ }
+
+ public Set<String> getCacheNames()
+ {
+ synchronized (caches)
+ {
+ return new HashSet<String>(caches.keySet());
+ }
+ }
+
+ public Cache<Object, Object> getCache(String configName, boolean create) throws Exception
+ {
+ Cache<Object, Object> cache = null;
+ synchronized (caches)
+ {
+ cache = (Cache<Object, Object>) caches.get(configName);
+ if (cache == null && create)
+ {
+ Configuration config = configRegistry.getConfiguration(configName);
+ if (channelFactory != null && config.getMultiplexerStack() != null) {
+ config.getRuntimeConfig().setMuxChannelFactory(channelFactory);
+ }
+ cache = DefaultCacheFactory.getInstance().createCache(config, false);
+ registerCache(cache, configName);
+ }
+ else if (cache != null)
+ {
+ incrementCheckout(configName);
+ }
+ }
+
+ return cache;
+ }
+
+ public void releaseCache(String configName)
+ {
+ synchronized (caches)
+ {
+ if (!caches.containsKey(configName))
+ throw new IllegalStateException(configName + " not registered");
+ if (decrementCheckout(configName) == 0)
+ {
+ Cache<Object, Object> cache = caches.remove(configName);
+ destroyCache(cache);
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------- Public
+
+ public ConfigurationRegistry getConfigurationRegistry()
+ {
+ return configRegistry;
+ }
+
+ public void setConfigurationRegistry(ConfigurationRegistry configRegistry)
+ {
+ this.configRegistry = configRegistry;
+ this.configRegistryInjected = true;
+ }
+
+ public void setChannelFactory(ChannelFactory channelFactory)
+ {
+ this.channelFactory = channelFactory;
+ }
+
+ public void registerCache(Cache<Object, Object> cache, String configName)
+ {
+ synchronized (caches)
+ {
+ if (caches.containsKey(configName))
+ throw new IllegalStateException(configName + " already registered");
+ caches.put(configName, cache);
+ incrementCheckout(configName);
+ }
+ }
+
+ public void start() throws Exception
+ {
+ if (!started)
+ {
+ if (configRegistry == null)
+ throw new IllegalStateException("Must configure a ConfigurationRegistry before calling start()");
+ if (channelFactory == null)
+ throw new IllegalStateException("Must provide a ChannelFactory before calling start()");
+
+ if (!configRegistryInjected)
+ {
+ ((XmlParsingConfigurationRegistry) configRegistry).start();
+ }
+
+ started = true;
+ }
+ }
+
+ public void stop()
+ {
+ if (started)
+ {
+ synchronized (caches)
+ {
+ for (Iterator<Map.Entry<String, Cache<Object, Object>>> it = caches.entrySet().iterator(); it.hasNext();)
+ {
+ Map.Entry<String, Cache<Object, Object>> entry = it.next();
+ destroyCache(entry.getValue());
+ it.remove();
+ }
+ caches.clear();
+ checkouts.clear();
+ }
+
+ if (!configRegistryInjected)
+ {
+ ((XmlParsingConfigurationRegistry) configRegistry).stop();
+ }
+
+ started = false;
+ }
+ }
+
+ // ---------------------------------------------------------------- Private
+
+ private int incrementCheckout(String configName)
+ {
+ synchronized (checkouts)
+ {
+ Integer count = (Integer) checkouts.get(configName);
+ if (count == null)
+ count = new Integer(0);
+ Integer newVal = new Integer(count.intValue() + 1);
+ checkouts.put(configName, newVal);
+ return newVal.intValue();
+ }
+ }
+
+ private int decrementCheckout(String configName)
+ {
+ synchronized (checkouts)
+ {
+ Integer count = (Integer) checkouts.get(configName);
+ if (count == null || count.intValue() < 1)
+ throw new IllegalStateException("invalid count of " + count + " for " + configName);
+
+ Integer newVal = new Integer(count.intValue() - 1);
+ checkouts.put(configName, newVal);
+ return newVal.intValue();
+ }
+ }
+
+ private void destroyCache(Cache<Object, Object> cache)
+ {
+ if (cache.getCacheStatus() == CacheStatus.STARTED)
+ {
+ cache.stop();
+ }
+ if (cache.getCacheStatus() != CacheStatus.DESTROYED && cache.getCacheStatus() != CacheStatus.INSTANTIATED)
+ {
+ cache.destroy();
+ }
+ }
+}
Property changes on: core/trunk/src/main/java/org/jboss/cache/CacheManagerImpl.java
___________________________________________________________________
Name: svn:executable
+ *
Copied: core/trunk/src/main/java/org/jboss/cache/config/ConfigurationRegistry.java (from rev 4727, core/trunk/src/main/java/org/jboss/cache/registry/ConfigurationRegistry.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/ConfigurationRegistry.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/config/ConfigurationRegistry.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.config;
+
+import java.util.Set;
+
+
+/**
+ * A registry for {@link Configuration}s.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface ConfigurationRegistry
+{
+ /**
+ * Gets a {@link Configuration#clone() clone} of the {@link Configuration}
+ * registered under the given name.
+ * <p>
+ * The returned object is a clone of the internally held configuration,
+ * so any changes made to it by the caller will not affect the internal
+ * state of this registry.
+ *
+ * @param configName the name of the configuration
+ * @return a <code>Configuration</code>. Will not be <code>null</code>.
+ * @throws IllegalArgumentException if no configuration is registered
+ * under <code>configName</code>
+ */
+ Configuration getConfiguration(String configName) throws Exception;
+
+ /**
+ * Register the given configuration under the given name.
+ * <p>
+ * The configuration will be cloned before being stored internally,
+ * so the copy under the control of the registry will not be affected
+ * by any external changes.
+ *
+ * @param configName the name of the configuration
+ * @param config the configuration
+ *
+ * @throws CloneNotSupportedException
+ * @throws IllegalStateException if a configuration is already registered
+ * under <code>configName</code>
+ */
+ void registerConfiguration(String configName, Configuration config) throws CloneNotSupportedException;
+
+ /**
+ * Unregisters the named configuration.
+ *
+ * @param configName the name of the configuration
+ * @throws IllegalStateException if no configuration is registered
+ * under <code>configName</code>
+ */
+ void unregisterConfiguration(String configName);
+
+ /**
+ * Gets the names of all registered configurations.
+ *
+ * @return
+ */
+ Set<String> getConfigurationNames();
+}
\ No newline at end of file
Copied: core/trunk/src/main/java/org/jboss/cache/config/XmlParsingConfigurationRegistry.java (from rev 4727, core/trunk/src/main/java/org/jboss/cache/registry/XmlParsingConfigurationRegistry.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/XmlParsingConfigurationRegistry.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/config/XmlParsingConfigurationRegistry.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.config;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.cache.factories.CacheConfigsXmlParser;
+
+/**
+ * {@link ConfigurationRegistry} that obtains its initial set of configurations
+ * by parsing an XML document.
+ *
+ * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public class XmlParsingConfigurationRegistry implements ConfigurationRegistry
+{
+ private CacheConfigsXmlParser parser;
+ private String configResource;
+ private Map<String, Configuration> configs = new Hashtable<String, Configuration>();
+ private boolean started;
+
+ public XmlParsingConfigurationRegistry(String configResource)
+ {
+ parser = new CacheConfigsXmlParser();
+ this.configResource = configResource;
+ }
+
+ public void start() throws Exception
+ {
+ if (!started)
+ {
+ configs.putAll(parser.parseConfigs(configResource));
+ started = true;
+ }
+ }
+
+ public void stop()
+ {
+ if (started)
+ {
+ synchronized (configs)
+ {
+ configs.clear();
+ }
+ started = false;
+ }
+ }
+
+ public String getConfigResource()
+ {
+ return configResource;
+ }
+
+ public Set<String> getConfigurationNames()
+ {
+ return new HashSet<String>(configs.keySet());
+ }
+
+ public void registerConfiguration(String configName, Configuration config)
+ throws CloneNotSupportedException
+ {
+ synchronized (configs) {
+ if (configs.containsKey(configName))
+ throw new IllegalStateException(configName + " already registered");
+ configs.put(configName, config.clone());
+ }
+ }
+
+ public void unregisterConfiguration(String configName)
+ {
+ synchronized (configs) {
+ if (configs.remove(configName) == null)
+ throw new IllegalStateException(configName + " not registered");
+ }
+ }
+
+ public Configuration getConfiguration(String configName)
+ {
+ Configuration config = null;
+ synchronized (configs)
+ {
+ config = configs.get(configName);
+ }
+
+ if (config == null)
+ throw new IllegalArgumentException("unknown config " + configName);
+
+ // Don't hand out a ref to our master copy
+ try
+ {
+ return config.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // This should not happen, as we already cloned the config
+ throw new RuntimeException("Could not clone configuration " + configName, e);
+ }
+ }
+}
Copied: core/trunk/src/main/java/org/jboss/cache/factories/CacheConfigsXmlParser.java (from rev 4727, core/trunk/src/main/java/org/jboss/cache/registry/CacheConfigsXmlParser.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/CacheConfigsXmlParser.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/CacheConfigsXmlParser.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -0,0 +1,141 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.cache.factories;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.xml.XmlHelper;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Parser able to parse a series of cache configurations stored in an
+ * XML document with the following structure:
+ * <pre>
+ * <cache-configs>
+ * <cache-config name="configA">
+ * ....
+ * </cache-config>
+ * <cache-config name="configB">
+ * ....
+ * </cache-config>
+ * </cache-configs>
+ * </pre>
+ * <p/>
+ * The '....' represents the normal content of the mbean element in a
+ * JBC -service.xml config file.
+ *
+ * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1.1 $
+ */
+public class CacheConfigsXmlParser
+ {
+ /** Name of the root element in a cache configs XML document*/
+ public static final String DOCUMENT_ROOT = "cache-configs";
+ /**
+ * Name of the element that represents an individual cache configuration
+ * in a cache configs XML document.
+ */
+ public static final String CONFIG_ROOT = "cache-config";
+ /**
+ * Name of the attribute in a {@link #CONFIG_ROOT cache-config} element that specifies
+ * the name of the configuration.
+ */
+ public static final String CONFIG_NAME = "name";
+
+ private static final Log log = LogFactory.getLog(CacheConfigsXmlParser.class);
+
+ private final XmlConfigurationParser parser = new XmlConfigurationParser();
+
+ public Map<String, Configuration> parseConfigs(String fileName) throws CloneNotSupportedException
+ {
+ InputStream is = getAsInputStreamFromClassLoader(fileName);
+ if (is == null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Unable to find configuration file " + fileName + " in classpath; searching for this file on the filesystem instead.");
+ try
+ {
+ is = new FileInputStream(fileName);
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new ConfigurationException("Unable to find config file " + fileName + " either in classpath or on the filesystem!", e);
+ }
+ }
+
+ return parseConfigs(is);
+ }
+
+ public Map<String, Configuration> parseConfigs(InputStream stream) throws CloneNotSupportedException
+ {
+ // loop through all elements in XML.
+ Element root = XmlHelper.getDocumentRoot(stream);
+ NodeList list = root.getElementsByTagName(CONFIG_ROOT);
+ if (list == null || list.getLength() == 0)
+ throw new ConfigurationException("Can't find " + CONFIG_ROOT + " tag");
+
+ Map<String, Configuration> result = new HashMap<String, Configuration>();
+
+ for (int i = 0; i < list.getLength(); i++)
+ {
+ Node node = list.item(i);
+ if (node.getNodeType() != Node.ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ Element element = (Element) node;
+ String name = element.getAttribute(CONFIG_NAME);
+ if (name == null || name.trim().length() == 0)
+ throw new ConfigurationException("Element " + element + " has no name attribute");
+
+ Configuration c = parser.parseConfiguration(element);
+ // Prove that we can successfully clone it
+ c = c.clone();
+ result.put(name.trim(), c);
+ }
+
+ return result;
+ }
+
+ protected InputStream getAsInputStreamFromClassLoader(String filename)
+ {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
+ if (is == null)
+ {
+ // check system class loader
+ is = getClass().getClassLoader().getResourceAsStream(filename);
+ }
+ return is;
+ }
+ }
\ No newline at end of file
Deleted: core/trunk/src/main/java/org/jboss/cache/registry/CacheConfigsXmlParser.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/registry/CacheConfigsXmlParser.java 2007-11-05 16:25:48 UTC (rev 4727)
+++ core/trunk/src/main/java/org/jboss/cache/registry/CacheConfigsXmlParser.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -1,122 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.cache.registry;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.ConfigurationException;
-import org.jboss.cache.factories.XmlConfigurationParser;
-import org.jboss.cache.xml.XmlHelper;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public class CacheConfigsXmlParser
- {
- /** Name of the root element in a cache configs XML document*/
- public static final String DOCUMENT_ROOT = "cache-configs";
- /**
- * Name of the element that represents an individual cache configuration
- * in a cache configs XML document.
- */
- public static final String CONFIG_ROOT = "cache-config";
- /**
- * Name of the attribute in a {@link #CONFIG_ROOT cache-config} element that specifies
- * the name of the configuration.
- */
- public static final String CONFIG_NAME = "name";
-
- private static final Log log = LogFactory.getLog(CacheConfigsXmlParser.class);
-
- private final XmlConfigurationParser parser = new XmlConfigurationParser();
-
- public Map<String, Configuration> parseConfigs(String fileName) throws CloneNotSupportedException
- {
- InputStream is = getAsInputStreamFromClassLoader(fileName);
- if (is == null)
- {
- if (log.isDebugEnabled())
- log.debug("Unable to find configuration file " + fileName + " in classpath; searching for this file on the filesystem instead.");
- try
- {
- is = new FileInputStream(fileName);
- }
- catch (FileNotFoundException e)
- {
- throw new ConfigurationException("Unable to find config file " + fileName + " either in classpath or on the filesystem!", e);
- }
- }
-
- return parseConfigs(is);
- }
-
- public Map<String, Configuration> parseConfigs(InputStream stream) throws CloneNotSupportedException
- {
- // loop through all elements in XML.
- Element root = XmlHelper.getDocumentRoot(stream);
- NodeList list = root.getElementsByTagName(CONFIG_ROOT);
- if (list == null || list.getLength() == 0)
- throw new ConfigurationException("Can't find " + CONFIG_ROOT + " tag");
-
- Map<String, Configuration> result = new HashMap<String, Configuration>();
-
- for (int i = 0; i < list.getLength(); i++)
- {
- Node node = list.item(i);
- if (node.getNodeType() != Node.ELEMENT_NODE)
- {
- continue;
- }
-
- Element element = (Element) node;
- String name = element.getAttribute(CONFIG_NAME);
- if (name == null || name.trim().length() == 0)
- throw new ConfigurationException("Element " + element + " has no name attribute");
-
- Configuration c = parser.parseConfiguration(element);
- // Prove that we can successfully clone it
- c = c.clone();
- result.put(name.trim(), c);
- }
-
- return result;
- }
-
- protected InputStream getAsInputStreamFromClassLoader(String filename)
- {
- InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
- if (is == null)
- {
- // check system class loader
- is = getClass().getClassLoader().getResourceAsStream(filename);
- }
- return is;
- }
- }
\ No newline at end of file
Deleted: core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistry.java 2007-11-05 16:25:48 UTC (rev 4727)
+++ core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistry.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -1,95 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.registry;
-
-import java.util.Set;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.config.Configuration;
-import org.jgroups.ChannelFactory;
-import org.jgroups.JChannelFactory;
-
-/**
- * Factory and registry for JBoss Cache instances configured using
- * named configurations.
- *
- * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
- * @version $Revision: 1 $
- */
-public interface CacheRegistry {
-
- /**
- * Gets the names of all the configurations of which this object
- * is aware.
- *
- * @return a set of names. Will not be <code>null</code>.
- */
- Set<String> getConfigurationNames();
-
- /**
- * Gets the name of all caches that are registered, i.e. that can be
- * by a call to {@link #getCache(String, boolean) getCache(name, false)}.
- *
- * @return a set of names. Will not be <code>null</code>.
- */
- Set<String> getCacheNames();
-
- /**
- * Gets the JGroups <code>ChannelFactory</code> that will be injected
- * into any {@link Configuration} that has a
- * {@link Configuration#getMultiplexerStack() multiplexer stack}
- * configured.
- *
- * @return
- */
- ChannelFactory getChannelFactory();
-
- /**
- * Get a cache configured according to the given configuration name,
- * optionally instantiating the cache if it hasn't already been
- * instantiated.
- * <p>
- * The caller is free to invoke the {@link Cache#create()} and
- * {@link Cache#start()} lifecycle methods on the returned cache, but
- * the @link Cache#stop()} and {@link Cache#destroy()} methods should not
- * be invoked, since it is quite possible other users are still using the
- * cache. Use {@link #releaseCache(String)} to notify this
- * registry that the caller is no longer using a cache; let the registry
- * control stopping and destroying the cache.
- * </p>
- * <p>
- * If invoking this method leads to the instantiation of the cache,
- * <code>create()</code> and <code>start()</code> will not be invoked
- * on the cache before it is returned.
- * </p>
- *
- * @param configName the name of the configuration
- * @param create should the cache be instantiated if it
- * hasn't already been?
- * @return the cache, or <code>null</code> if
- * <code>create</code> is false and the cache hasn't
- * been created previously.
- *
- * @throws IllegalArgumentException if this object is unaware of
- * <code>configName</code>; i.e. the set
- * returned from {@link #getConfigurationNames()}
- * does not include <code>configName</code>
- * @throws Exception if there is a problem instantiating the cache
- */
- Cache<Object, Object> getCache(String configName, boolean create) throws Exception;
-
- /**
- * Notifies the registry that the caller is no longer using the given
- * cache. The registry may perform cleanup operations, such as
- * stopping and destroying the cache.
- *
- * @param configName
- */
- void releaseCache(String configName);
-
-}
\ No newline at end of file
Deleted: core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistryImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistryImpl.java 2007-11-05 16:25:48 UTC (rev 4727)
+++ core/trunk/src/main/java/org/jboss/cache/registry/CacheRegistryImpl.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received a
- * copy of the GNU Lesser General Public License, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Brian Stansberry
- */
-
-package org.jboss.cache.registry;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheStatus;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.config.Configuration;
-import org.jgroups.ChannelFactory;
-
-/**
- * Basic implementation of {@link CacheRegistry}.
- *
- * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
- * @version $Revision: 1 $
- */
-public class CacheRegistryImpl implements CacheRegistry
-{
- private ConfigurationRegistry configRegistry;
-
- private boolean configRegistryInjected;
-
- private Map<String, Cache<Object, Object>> caches = new HashMap<String, Cache<Object, Object>>();
-
- private Map<String, Integer> checkouts = new HashMap<String, Integer>();
-
- private ChannelFactory channelFactory;
-
- private boolean started;
-
- /**
- * Create a new CacheRegistryImpl.
- */
- public CacheRegistryImpl()
- {
- }
-
- /**
- * Create a new CacheRegistryImpl using the provided ConfigurationRegistry
- * and ChannelFactory.
- */
- public CacheRegistryImpl(ConfigurationRegistry configRegistry, ChannelFactory factory)
- {
- this.configRegistry = configRegistry;
- this.configRegistryInjected = true;
- this.channelFactory = factory;
- }
-
- /**
- * Create a new CacheRegistryImpl using the provided ChannelFactory and
- * using the provided file name to create an
- * {@link XmlParsingConfigurationRegistry}.
- */
- public CacheRegistryImpl(String configFileName, ChannelFactory factory)
- {
- configRegistry = new XmlParsingConfigurationRegistry(configFileName);
- this.channelFactory = factory;
- }
-
- // ---------------------------------------------------------- CacheRegistry
-
- public ChannelFactory getChannelFactory()
- {
- return channelFactory;
- }
-
- @SuppressWarnings("unchecked")
- public Set<String> getConfigurationNames()
- {
- synchronized (caches)
- {
- Set<String> configNames = configRegistry == null ? new HashSet<String>()
- : configRegistry.getConfigurationNames();
- configNames.addAll(getCacheNames());
- return configNames;
- }
- }
-
- public Set<String> getCacheNames()
- {
- synchronized (caches)
- {
- return new HashSet<String>(caches.keySet());
- }
- }
-
- public Cache<Object, Object> getCache(String configName, boolean create) throws Exception
- {
- Cache<Object, Object> cache = null;
- synchronized (caches)
- {
- cache = (Cache<Object, Object>) caches.get(configName);
- if (cache == null && create)
- {
- Configuration config = configRegistry.getConfiguration(configName);
- if (channelFactory != null && config.getMultiplexerStack() != null) {
- config.getRuntimeConfig().setMuxChannelFactory(channelFactory);
- }
- cache = DefaultCacheFactory.getInstance().createCache(config, false);
- registerCache(cache, configName);
- }
- else if (cache != null)
- {
- incrementCheckout(configName);
- }
- }
-
- return cache;
- }
-
- public void releaseCache(String configName)
- {
- synchronized (caches)
- {
- if (!caches.containsKey(configName))
- throw new IllegalStateException(configName + " not registered");
- if (decrementCheckout(configName) == 0)
- {
- Cache<Object, Object> cache = caches.remove(configName);
- destroyCache(cache);
- }
- }
- }
-
- // ----------------------------------------------------------------- Public
-
- public ConfigurationRegistry getConfigurationRegistry()
- {
- return configRegistry;
- }
-
- public void setConfigurationRegistry(ConfigurationRegistry configRegistry)
- {
- this.configRegistry = configRegistry;
- this.configRegistryInjected = true;
- }
-
- public void setChannelFactory(ChannelFactory channelFactory)
- {
- this.channelFactory = channelFactory;
- }
-
- public void registerCache(Cache<Object, Object> cache, String configName)
- {
- synchronized (caches)
- {
- if (caches.containsKey(configName))
- throw new IllegalStateException(configName + " already registered");
- caches.put(configName, cache);
- incrementCheckout(configName);
- }
- }
-
- public void start() throws Exception
- {
- if (!started)
- {
- if (configRegistry == null)
- throw new IllegalStateException("Must configure a ConfigurationRegistry before calling start()");
- if (channelFactory == null)
- throw new IllegalStateException("Must provide a ChannelFactory before calling start()");
-
- if (!configRegistryInjected)
- {
- ((XmlParsingConfigurationRegistry) configRegistry).start();
- }
-
- started = true;
- }
- }
-
- public void stop()
- {
- if (started)
- {
- synchronized (caches)
- {
- for (Iterator<Map.Entry<String, Cache<Object, Object>>> it = caches.entrySet().iterator(); it.hasNext();)
- {
- Map.Entry<String, Cache<Object, Object>> entry = it.next();
- destroyCache(entry.getValue());
- it.remove();
- }
- caches.clear();
- checkouts.clear();
- }
-
- if (!configRegistryInjected)
- {
- ((XmlParsingConfigurationRegistry) configRegistry).stop();
- }
-
- started = false;
- }
- }
-
- // ---------------------------------------------------------------- Private
-
- private int incrementCheckout(String configName)
- {
- synchronized (checkouts)
- {
- Integer count = (Integer) checkouts.get(configName);
- if (count == null)
- count = new Integer(0);
- Integer newVal = new Integer(count.intValue() + 1);
- checkouts.put(configName, newVal);
- return newVal.intValue();
- }
- }
-
- private int decrementCheckout(String configName)
- {
- synchronized (checkouts)
- {
- Integer count = (Integer) checkouts.get(configName);
- if (count == null || count.intValue() < 1)
- throw new IllegalStateException("invalid count of " + count + " for " + configName);
-
- Integer newVal = new Integer(count.intValue() - 1);
- checkouts.put(configName, newVal);
- return newVal.intValue();
- }
- }
-
- private void destroyCache(Cache<Object, Object> cache)
- {
- if (cache.getCacheStatus() == CacheStatus.STARTED)
- {
- cache.stop();
- }
- if (cache.getCacheStatus() != CacheStatus.DESTROYED && cache.getCacheStatus() != CacheStatus.INSTANTIATED)
- {
- cache.destroy();
- }
- }
-}
Deleted: core/trunk/src/main/java/org/jboss/cache/registry/ConfigurationRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/registry/ConfigurationRegistry.java 2007-11-05 16:25:48 UTC (rev 4727)
+++ core/trunk/src/main/java/org/jboss/cache/registry/ConfigurationRegistry.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -1,67 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.registry;
-
-import java.util.Set;
-
-import org.jboss.cache.config.Configuration;
-
-/**
- * A registry for {@link Configuration}s.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public interface ConfigurationRegistry
-{
- /**
- * Gets a {@link Configuration#clone() clone} of the {@link Configuration}
- * registered under the given name.
- * <p>
- * The returned object is a clone of the internally held configuration,
- * so any changes made to it by the caller will not affect the internal
- * state of this registry.
- *
- * @param configName the name of the configuration
- * @return a <code>Configuration</code>. Will not be <code>null</code>.
- * @throws IllegalArgumentException if no configuration is registered
- * under <code>configName</code>
- */
- Configuration getConfiguration(String configName) throws Exception;
-
- /**
- * Register the given configuration under the given name.
- * <p>
- * The configuration will be cloned before being stored internally,
- * so the copy under the control of the registry will not be affected
- * by any external changes.
- *
- * @param configName the name of the configuration
- * @param config the configuration
- *
- * @throws CloneNotSupportedException
- * @throws IllegalStateException if a configuration is already registered
- * under <code>configName</code>
- */
- void registerConfiguration(String configName, Configuration config) throws CloneNotSupportedException;
-
- /**
- * Unregisters the named configuration.
- *
- * @param configName the name of the configuration
- * @throws IllegalStateException if no configuration is registered
- * under <code>configName</code>
- */
- void unregisterConfiguration(String configName);
-
- /**
- * Gets the names of all registered configurations.
- *
- * @return
- */
- Set<String> getConfigurationNames();
-}
\ No newline at end of file
Deleted: core/trunk/src/main/java/org/jboss/cache/registry/XmlParsingConfigurationRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/registry/XmlParsingConfigurationRegistry.java 2007-11-05 16:25:48 UTC (rev 4727)
+++ core/trunk/src/main/java/org/jboss/cache/registry/XmlParsingConfigurationRegistry.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -1,108 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.registry;
-
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.cache.config.Configuration;
-
-/**
- * {@link ConfigurationRegistry} that obtains its initial set of configurations
- * by parsing an XML document.
- *
- * @author <a href="brian.stansberry(a)jboss.com">Brian Stansberry</a>
- * @version $Revision: 1 $
- */
-public class XmlParsingConfigurationRegistry implements ConfigurationRegistry
-{
- private CacheConfigsXmlParser parser;
- private String configResource;
- private Map<String, Configuration> configs = new Hashtable<String, Configuration>();
- private boolean started;
-
- public XmlParsingConfigurationRegistry(String configResource)
- {
- parser = new CacheConfigsXmlParser();
- this.configResource = configResource;
- }
-
- public void start() throws Exception
- {
- if (!started)
- {
- configs.putAll(parser.parseConfigs(configResource));
- started = true;
- }
- }
-
- public void stop()
- {
- if (started)
- {
- synchronized (configs)
- {
- configs.clear();
- }
- started = false;
- }
- }
-
- public String getConfigResource()
- {
- return configResource;
- }
-
- public Set<String> getConfigurationNames()
- {
- return new HashSet<String>(configs.keySet());
- }
-
- public void registerConfiguration(String configName, Configuration config)
- throws CloneNotSupportedException
- {
- synchronized (configs) {
- if (configs.containsKey(configName))
- throw new IllegalStateException(configName + " already registered");
- configs.put(configName, config.clone());
- }
- }
-
- public void unregisterConfiguration(String configName)
- {
- synchronized (configs) {
- if (configs.remove(configName) == null)
- throw new IllegalStateException(configName + " not registered");
- }
- }
-
- public Configuration getConfiguration(String configName)
- {
- Configuration config = null;
- synchronized (configs)
- {
- config = configs.get(configName);
- }
-
- if (config == null)
- throw new IllegalArgumentException("unknown config " + configName);
-
- // Don't hand out a ref to our master copy
- try
- {
- return config.clone();
- }
- catch (CloneNotSupportedException e)
- {
- // This should not happen, as we already cloned the config
- throw new RuntimeException("Could not clone configuration " + configName, e);
- }
- }
-}
Copied: core/trunk/src/test/java/org/jboss/cache/manager (from rev 4727, core/trunk/src/test/java/org/jboss/cache/registry)
Copied: core/trunk/src/test/java/org/jboss/cache/manager/CacheManagerTest.java (from rev 4727, core/trunk/src/test/java/org/jboss/cache/registry/CacheRegistryTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/manager/CacheManagerTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/manager/CacheManagerTest.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.manager;
+
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheManagerImpl;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationRegistry;
+import org.jgroups.JChannelFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Tests CacheRegistryImpl.
+ *
+ * @author Brian Stansberry
+ */
+@Test(groups = {"functional"})
+public class CacheManagerTest
+{
+ /** A file that includes every configuration element I could think of */
+ public static final String DEFAULT_CONFIGURATION_FILE = "META-INF/jbc2-configs.xml";
+
+ private Set<Cache<Object, Object>> caches = new HashSet<Cache<Object, Object>>();
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws Exception
+ {
+ for (Cache<Object, Object> cache : caches)
+ {
+ try
+ {
+ cache.stop();
+ cache.destroy();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.out);
+ }
+ }
+ }
+
+ /**
+ * A test that instantiates a CacheRegistryImpl and cycles through all its
+ * configs, creating and releasing each.
+ *
+ * TODO It's late; I just put a bunch of stuff in one test method.
+ * Refactor or something.
+ *
+ * @throws Exception
+ */
+ public void testBasic() throws Exception
+ {
+ JChannelFactory cf = new JChannelFactory();
+ cf.setMultiplexerConfig("stacks.xml"); // the default stacks in jgroups.jar
+ CacheManagerImpl registry = new CacheManagerImpl(DEFAULT_CONFIGURATION_FILE, cf);
+ registry.start();
+
+ ConfigurationRegistry configRegistry = registry.getConfigurationRegistry();
+
+ Set<String> configNames = registry.getConfigurationNames();
+ assertEquals(7, configNames.size());
+ Set<String> cacheNames = registry.getCacheNames();
+ assertEquals(0, cacheNames.size());
+
+ for (String configName : configNames)
+ {
+ assertNull(configName + " not created", registry.getCache(configName, false));
+ Cache<Object, Object> cache = registry.getCache(configName, true);
+ caches.add(cache);
+
+ // Cache shouldn't be started
+ assertEquals(CacheStatus.INSTANTIATED, cache.getCacheStatus());
+ cache.create();
+ cache.start();
+
+ // Config should be a clone
+ Configuration rawConfig = configRegistry.getConfiguration(configName);
+ Configuration realConfig = cache.getConfiguration();
+ assertFalse(rawConfig == realConfig);
+ assertEquals(rawConfig.getClusterName(), realConfig.getClusterName());
+ }
+
+ cacheNames = registry.getCacheNames();
+ assertEquals(configNames, cacheNames);
+
+ // Test basic releasing of caches
+ for (String configName : configNames)
+ {
+ registry.releaseCache(configName);
+ }
+
+ cacheNames = registry.getCacheNames();
+ assertEquals(0, cacheNames.size());
+
+ // We shouldn't have affected configuration set
+ Set<String> configNames2 = registry.getConfigurationNames();
+ assertEquals(configNames, configNames2);
+
+ // Releasing only checkout of cache should have destroyed it
+ for (Iterator<Cache<Object, Object>> it = caches.iterator(); it.hasNext();)
+ {
+ assertEquals(CacheStatus.DESTROYED, it.next().getCacheStatus());
+ it.remove();
+ }
+
+ // Get cache w/o asking to create returns null
+ String configName = configNames.iterator().next();
+ assertNull(configName + " not created", registry.getCache(configName, false));
+ // Get cache w/ asking to create returns cache
+ Cache<Object, Object> cache = registry.getCache(configName, true);
+ assertFalse(null == cache);
+ caches.add(cache);
+
+ cache.create();
+ cache.start();
+
+ // Test 2 checkouts of the same cache
+ Cache<Object, Object> cache2 = registry.getCache(configName, true);
+ assertTrue(cache == cache2);
+
+ registry.releaseCache(configName);
+
+ // One release does not cause registry to stop cache
+ assertEquals(CacheStatus.STARTED, cache.getCacheStatus());
+
+ registry.stop();
+
+ // Now it's stopped
+ assertEquals(CacheStatus.DESTROYED, cache.getCacheStatus());
+ caches.remove(cache);
+
+ cacheNames = registry.getCacheNames();
+ assertEquals(0, cacheNames.size());
+ assertEquals(cacheNames, registry.getConfigurationNames());
+ }
+}
Deleted: core/trunk/src/test/java/org/jboss/cache/manager/CacheRegistryTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/registry/CacheRegistryTest.java 2007-11-05 16:25:48 UTC (rev 4727)
+++ core/trunk/src/test/java/org/jboss/cache/manager/CacheRegistryTest.java 2007-11-06 03:36:23 UTC (rev 4728)
@@ -1,141 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.registry;
-
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertNull;
-import static org.testng.AssertJUnit.assertTrue;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheStatus;
-import org.jboss.cache.config.Configuration;
-import org.jgroups.JChannelFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-/**
- * Tests CacheRegistryImpl.
- *
- * @author Brian Stansberry
- */
-@Test(groups = {"functional"})
-public class CacheRegistryTest
-{
- /** A file that includes every configuration element I could think of */
- public static final String DEFAULT_CONFIGURATION_FILE = "META-INF/jbc2-configs.xml";
-
- private Set<Cache<Object, Object>> caches = new HashSet<Cache<Object, Object>>();
-
- @AfterMethod(alwaysRun = true)
- public void tearDown() throws Exception
- {
- for (Cache<Object, Object> cache : caches)
- {
- try
- {
- cache.stop();
- cache.destroy();
- }
- catch (Exception e)
- {
- e.printStackTrace(System.out);
- }
- }
- }
-
- /**
- * A test that instantiates a CacheRegistryImpl and cycles through all its
- * configs, creating and releasing each.
- *
- * TODO It's late; I just put a bunch of stuff in one test method.
- * Refactor or something.
- *
- * @throws Exception
- */
- public void testBasic() throws Exception
- {
- JChannelFactory cf = new JChannelFactory();
- cf.setMultiplexerConfig("stacks.xml"); // the default stacks in jgroups.jar
- CacheRegistryImpl registry = new CacheRegistryImpl(DEFAULT_CONFIGURATION_FILE, cf);
- registry.start();
-
- ConfigurationRegistry configRegistry = registry.getConfigurationRegistry();
-
- Set<String> configNames = registry.getConfigurationNames();
- assertEquals(7, configNames.size());
- Set<String> cacheNames = registry.getCacheNames();
- assertEquals(0, cacheNames.size());
-
- for (String configName : configNames)
- {
- assertNull(configName + " not created", registry.getCache(configName, false));
- Cache<Object, Object> cache = registry.getCache(configName, true);
- caches.add(cache);
- assertEquals(CacheStatus.INSTANTIATED, cache.getCacheStatus());
- cache.create();
- cache.start();
- Configuration rawConfig = configRegistry.getConfiguration(configName);
- Configuration realConfig = cache.getConfiguration();
- assertFalse(rawConfig == realConfig);
- assertEquals(rawConfig.getClusterName(), realConfig.getClusterName());
- }
-
- cacheNames = registry.getCacheNames();
- assertEquals(configNames, cacheNames);
-
- for (String configName : configNames)
- {
- registry.releaseCache(configName);
- }
-
- cacheNames = registry.getCacheNames();
- assertEquals(0, cacheNames.size());
-
- Set<String> configNames2 = registry.getConfigurationNames();
- assertEquals(configNames, configNames2);
-
- for (Iterator<Cache<Object, Object>> it = caches.iterator(); it.hasNext();)
- {
- assertEquals(CacheStatus.DESTROYED, it.next().getCacheStatus());
- it.remove();
- }
-
- String configName = configNames.iterator().next();
- assertNull(configName + " not created", registry.getCache(configName, false));
- Cache<Object, Object> cache = registry.getCache(configName, true);
- assertFalse(null == cache);
- caches.add(cache);
-
- cache.create();
- cache.start();
-
- Cache<Object, Object> cache2 = registry.getCache(configName, true);
-
- assertTrue(cache == cache2);
-
- registry.releaseCache(configName);
-
- // One release does not cause registry to stop cache
- assertEquals(CacheStatus.STARTED, cache.getCacheStatus());
-
- registry.stop();
-
- // Now it's stopped
- assertEquals(CacheStatus.DESTROYED, cache.getCacheStatus());
- caches.remove(cache);
-
- cacheNames = registry.getCacheNames();
- assertEquals(0, cacheNames.size());
- assertEquals(cacheNames, registry.getConfigurationNames());
- }
-}
17 years, 1 month
JBoss Cache SVN: r4727 - in core/trunk/src: main/java/org/jboss/cache/interceptors and 3 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2007-11-05 11:25:48 -0500 (Mon, 05 Nov 2007)
New Revision: 4727
Modified:
core/trunk/src/main/java/org/jboss/cache/CacheImpl.java
core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.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/transaction/TransactionTable.java
core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java
core/trunk/src/test/java/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java
Log:
JBCACHE-923 - reduces the likelihood of race conditions described.
Modified: core/trunk/src/main/java/org/jboss/cache/CacheImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/CacheImpl.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/main/java/org/jboss/cache/CacheImpl.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -48,18 +48,7 @@
import org.jboss.cache.util.concurrent.ConcurrentHashSet;
import org.jboss.util.stream.MarshalledValueInputStream;
import org.jboss.util.stream.MarshalledValueOutputStream;
-import org.jgroups.Address;
-import org.jgroups.Channel;
-import org.jgroups.ChannelClosedException;
-import org.jgroups.ChannelException;
-import org.jgroups.ChannelFactory;
-import org.jgroups.ChannelNotConnectedException;
-import org.jgroups.ExtendedMembershipListener;
-import org.jgroups.ExtendedMessageListener;
-import org.jgroups.JChannel;
-import org.jgroups.Message;
-import org.jgroups.StateTransferException;
-import org.jgroups.View;
+import org.jgroups.*;
import org.jgroups.blocks.GroupRequest;
import org.jgroups.blocks.RpcDispatcher;
import org.jgroups.blocks.RspFilter;
@@ -77,16 +66,7 @@
import java.io.NotSerializableException;
import java.io.OutputStream;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -4028,7 +4008,7 @@
}
catch (Throwable t)
{
- throw new RuntimeException(t);
+ throw new CacheException(t);
}
finally
{
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -23,6 +23,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheException;
import org.jboss.cache.CacheSPI;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.config.Configuration;
@@ -180,6 +181,22 @@
}
}
+ /**
+ * Tests whether the caller is in a valid transaction. If not, will throw a CacheException.
+ */
+ protected void assertTransactionValid(InvocationContext ctx)
+ {
+ Transaction tx = ctx.getTransaction();
+ if (!isValid(tx)) try
+ {
+ throw new CacheException("Invalid transaction " + tx + ", status = " + (tx == null ? null : tx.getStatus()));
+ }
+ catch (SystemException e)
+ {
+ throw new CacheException("Exception trying to analyse status of transaction " + tx, e);
+ }
+ }
+
public String toString()
{
return getClass().getName()
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -6,6 +6,7 @@
*/
package org.jboss.cache.interceptors;
+import org.jboss.cache.CacheException;
import org.jboss.cache.CacheImpl;
import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
@@ -271,6 +272,12 @@
Object child_name;
Thread currentThread = Thread.currentThread();
GlobalTransaction gtx = ctx.getGlobalTransaction();
+ // if the tx associated with the current thread is rolling back, barf! JBCACHE-923
+ if (gtx != null)
+ {
+ assertTransactionValid(ctx);
+ }
+
Object owner = (gtx != null) ? gtx : currentThread;
int treeNodeSize;
@@ -428,7 +435,16 @@
{
// add the lock to the list of locks maintained for this transaction
// (needed for release of locks on commit or rollback)
- cache.getTransactionTable().addLock(gtx, lock);
+ try
+ {
+ cache.getTransactionTable().addLock(gtx, lock);
+ }
+ catch (CacheException e)
+ {
+ // may happen, if the transaction entry does not exist
+ lock.release(gtx);
+ throw e;
+ }
}
else
{
@@ -518,9 +534,13 @@
private void cleanup(GlobalTransaction gtx)
{
+ if (log.isTraceEnabled()) log.trace("Cleaning up locks for gtx " + gtx);
TransactionEntry entry = tx_table.get(gtx);
// Let's do it in stack style, LIFO
- entry.releaseAllLocksLIFO(gtx);
+ if (entry != null)
+ entry.releaseAllLocksLIFO(gtx);
+ else
+ log.error("No transaction entry present!!", new Throwable());
/*
Transaction ltx = entry.getTransaction();
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -7,7 +7,6 @@
package org.jboss.cache.interceptors;
import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.ReplicationException;
import org.jboss.cache.config.Configuration;
@@ -243,7 +242,7 @@
setTransactionalContext(ltx, gtx, ctx);
// register a sync handler for this tx.
- registerHandler(ltx, new RemoteSynchronizationHandler(gtx, ltx, cache), ctx);
+ registerHandler(ltx, new RemoteSynchronizationHandler(gtx, ltx), ctx);
if (configuration.isNodeLockingOptimistic())
{
@@ -895,7 +894,7 @@
log.trace("Registering sync handler for tx " + tx + ", gtx " + gtx);
}
// see the comment in the LocalSyncHandler for the last isOriginLocal param.
- LocalSynchronizationHandler myHandler = new LocalSynchronizationHandler(gtx, tx, cache, !ctx.isOriginLocal());
+ LocalSynchronizationHandler myHandler = new LocalSynchronizationHandler(gtx, tx, !ctx.isOriginLocal());
registerHandler(tx, myHandler, ctx);
}
}
@@ -998,17 +997,16 @@
{
Transaction tx = null;
GlobalTransaction gtx = null;
- CacheSPI cache = null;
+// CacheSPI cache = null;
List modifications = null;
TransactionEntry entry = null;
protected InvocationContext ctx; // the context for this call.
- RemoteSynchronizationHandler(GlobalTransaction gtx, Transaction tx, CacheSPI cache)
+ RemoteSynchronizationHandler(GlobalTransaction gtx, Transaction tx)
{
this.gtx = gtx;
this.tx = tx;
- this.cache = cache;
}
public void beforeCompletion()
@@ -1057,7 +1055,7 @@
modifications = entry.getModifications();
ctx.setOptionOverrides(entry.getOption());
}
- transactions.remove(tx);
+ if (tx != null) transactions.remove(tx);
switch (status)
{
@@ -1101,7 +1099,6 @@
{
this.tx = null;
this.gtx = null;
- this.cache = null;
this.modifications = null;
this.entry = null;
}
@@ -1141,12 +1138,11 @@
*
* @param gtx
* @param tx
- * @param cache
* @param remoteLocal
*/
- LocalSynchronizationHandler(GlobalTransaction gtx, Transaction tx, CacheSPI cache, boolean remoteLocal)
+ LocalSynchronizationHandler(GlobalTransaction gtx, Transaction tx, boolean remoteLocal)
{
- super(gtx, tx, cache);
+ super(gtx, tx);
this.remoteLocal = remoteLocal;
}
@@ -1188,7 +1184,7 @@
}
break;
default:
- throw new CacheException("transaction " + tx + " in status " + tx.getStatus() + " unbale to start transaction");
+ throw new CacheException("transaction " + tx + " in status " + tx.getStatus() + " unable to start transaction");
}
}
catch (Throwable t)
@@ -1221,6 +1217,8 @@
if (ctx == null) ctx = cache.getInvocationContext();
ctx.setLocalRollbackOnly(localRollbackOnly);
ctx.setOptionOverrides(transactionalOptions);
+ ctx.setTransaction(tx);
+ ctx.setGlobalTransaction(gtx);
try
{
super.afterCompletion(status);
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -8,6 +8,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheException;
import org.jboss.cache.lock.NodeLock;
import org.jboss.cache.marshall.MethodCall;
@@ -210,8 +211,7 @@
TransactionEntry entry = get(gtx);
if (entry == null)
{
- log.error("transaction entry not found for (gtx=" + gtx + ")");
- return;
+ throw new CacheException("Unable to record lock for transaction " + gtx + " since no transaction entry exists!");
}
entry.addLock(l);
}
Modified: core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -416,4 +416,29 @@
}
}
}
+
+ /**
+ * Clears any associated transactions with the current thread in the caches' transaction managers.
+ */
+ public static void killTransactions(Cache... caches)
+ {
+ for (Cache c: caches)
+ {
+ if (c != null && c.getCacheStatus() == CacheStatus.STARTED)
+ {
+ CacheImpl ci = (CacheImpl) c;
+ if (ci.getTransactionManager() != null)
+ {
+ try
+ {
+ ci.getTransactionManager().rollback();
+ }
+ catch (Exception e)
+ {
+ // don't care
+ }
+ }
+ }
+ }
+ }
}
Modified: core/trunk/src/test/java/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java 2007-11-03 02:27:34 UTC (rev 4726)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/SimultaneousRollbackAndPutTest.java 2007-11-05 16:25:48 UTC (rev 4727)
@@ -1,9 +1,14 @@
package org.jboss.cache.transaction;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
import org.jboss.cache.CacheImpl;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
+import org.jboss.cache.misc.TestingUtil;
+import org.jboss.cache.util.CachePrinter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
@@ -20,12 +25,13 @@
*
* @author <a href="mailto:manik@jboss.org">Manik Surtani</a>
*/
-@Test(groups = {"functional", "transaction"}, enabled = false) // Known issue - disabled because of JBCACHE-923
+@Test(groups = {"functional", "transaction"}, enabled = true) // Known issue - disabled because of JBCACHE-923
public class SimultaneousRollbackAndPutTest
{
private Cache cache;
private TransactionManager tm;
private Fqn A = Fqn.fromString("/a"), B = Fqn.fromString("/b");
+ private Log log = LogFactory.getLog(SimultaneousRollbackAndPutTest.class);
@BeforeTest(alwaysRun = true)
protected void setUp() throws Exception
@@ -40,18 +46,30 @@
@AfterTest(alwaysRun = true)
protected void tearDown()
{
- cache.stop();
+ TestingUtil.killCaches(cache);
}
@AfterMethod(alwaysRun = true)
- protected void resetCache()
+ protected void resetCache() throws Exception
{
- cache.removeNode(B);
- cache.getRoot().getChild(A).clearData();
- cache.put(A, "k", "v");
+ try
+ {
+ cache.removeNode(B);
+ cache.getRoot().getChild(A).clearData();
+ cache.put(A, "k", "v");
+ // make sure we clean up any txs associa with the thread
+ TestingUtil.killTransactions(cache);
+ }
+ catch (Exception e)
+ {
+ // restart the cache
+ tearDown();
+ setUp();
+ }
+
}
- @Test(invocationCount = 200, alwaysRun = false, enabled = false)
+ @Test(invocationCount = 100, alwaysRun = false, enabled = false, description = "This is to do with a flaw in the way pessimistic locking deals with transactions. See JBCACHE-923")
public void testStaleLocks() throws Exception
{
// scenario:
@@ -63,7 +81,7 @@
cache.put(B, "k", "v");
// now the container should attempt to rollback the tx in a separate thread.
- new Thread()
+ Thread rollbackThread = new Thread("RollbackThread")
{
public void run()
{
@@ -76,19 +94,34 @@
exceptions.add(e);
}
}
- }.start();
+ };
+ rollbackThread.start();
- // now try and put stuff in the main thread again
- cache.put(A, "k2", "v2");
try
{
+ // now try and put stuff in the main thread again
+ cache.put(A, "k2", "v2");
tm.commit();
+// assert false : "Should never reach here";
}
catch (RollbackException expected)
{
// this is expected.
}
+ catch (CacheException ce)
+ {
+ // also expected at times
+ }
+ rollbackThread.join();
+
+ if (((CacheImpl) cache).getNumberOfLocksHeld() > 0)
+ {
+ log.fatal("***********");
+ log.fatal(CachePrinter.printCacheLockingInfo(cache));
+ log.fatal("***********");
+ }
+
assert 0 == ((CacheImpl) cache).getNumberOfLocksHeld();
if (exceptions.size() > 0) throw ((Exception) exceptions.get(0));
17 years, 2 months
JBoss Cache SVN: r4726 - in pojo/tags: 2.1.0.CR1 and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2007-11-02 22:27:34 -0400 (Fri, 02 Nov 2007)
New Revision: 4726
Added:
pojo/tags/2.1.0.CR1/
pojo/tags/2.1.0.CR1/README-Maven.txt
pojo/tags/2.1.0.CR1/assembly/
pojo/tags/2.1.0.CR1/pom.xml
pojo/tags/2.1.0.CR1/src/
Removed:
pojo/tags/2.1.0.CR1/README-Maven.txt
pojo/tags/2.1.0.CR1/assembly/
pojo/tags/2.1.0.CR1/pom.xml
pojo/tags/2.1.0.CR1/src/
Log:
tag CR1
Copied: pojo/tags/2.1.0.CR1 (from rev 4718, pojo/branches/2.1)
Deleted: pojo/tags/2.1.0.CR1/README-Maven.txt
===================================================================
--- pojo/branches/2.1/README-Maven.txt 2007-10-31 22:10:53 UTC (rev 4718)
+++ pojo/tags/2.1.0.CR1/README-Maven.txt 2007-11-03 02:27:34 UTC (rev 4726)
@@ -1,104 +0,0 @@
-Working with Maven
-------------------
-
-Requirements:
-
-* Java 5.0 and above
-* Maven 2.x
-
-Typical lifecycle phases
-------------------------
-
-Maven will create a target/ directory under the root for the creation of
-output at every stage.
-
-* mvn clean: cleans out any old builds and binaries
-
-* mvn compile: compiles java source code.
-
-* mvn test: runs the TestNG unit test suite on the compiled code. Will also compile the tests.
-
-* mvn package: packages the module as a jar file and builds the javadocs and user documentation from docbook sources.
-
-* mvn install: will install the artifacts in your local repo for use by other projects (such as JBoss Cache POJO edition which depends on JBoss Cache Core). Will also use Maven's assembly plugin to build ZIP files for download (in target/distribution)
-
-* mvn deploy: will build and deploy the project to the JBoss snapshots repository. Note that you should have your WebDAV username and password set up. (Deploys snapshots to http://snapshots.jboss.org/maven2/org/jboss/cache/). If you have a non-SNAPSHOT version number in your pom.xml, it will be deployed to the live releases repository (see below)
-
-
-Setting up your WebDAV username and password to deploy project snapshots
-------------------------------------------------------------------------
-
-You will also have to configure maven to use your username and password to access this repository. For this, you will have to modify the servers section of maven settings file ($MAVEN_HOME/conf/settings.xml, or ~/.m2/settings.xml). Something similar to the following should be added:
-
-<settings>
-
-...
-
- <servers>
-...
- <server>
- <id>snapshots.jboss.org</id>
- <username>webdav-user</username>
- <password>webdav-pass</password>
- </server>
-...
-
- </servers>
-
-...
-
-</settings>
-
-Deploying a release to a live repository
-----------------------------------------
-
-Very simple. Make sure you have the version number in your pom.xml set to a non-SNAPSHOT version. Maven will pick up on this and deploy to your release repository rather than the snapshot repository.
-
-Sadly JBoss release repository cannot be accessed via WebDAV, as the snapshot repository can. So what you need to do is:
-
-1) Check out the release repository from Subversion (svn co https://svn.jboss.org/repos/repository.jboss.org/maven2)
-2) Add a property in ~/.m2/settings.xml to point to this 'local' copy of the repo. (See maven settings below)
-3) Update your project's pom.xml to reflect a non-SNAPSHOT version number
-4) Deploy your project (mvn clean deploy)
-5) Check in your 'local' copy of the repo checked out in (1), adding any new directories/files created by (4).
-
-Maven settings.xml
-------------------
-
-Working with the JBoss Cache source tree, I have configured my ~/.m2/settings.xml to look like:
-
-<settings>
-
- <servers>
- <server>
- <id>snapshots.jboss.org</id>
- <username>MY_JBOSS_ORG_USERNAME</username>
- <password>WONT_TELL_YOU</password>
- </server>
- </servers>
-
-
- <profiles>
- <profile>
- <id>jboss</id>
- <properties>
- <maven.repository.root>/Users/manik/Code/maven2</maven.repository.root>
- </properties>
- </profile>
- </profiles>
-
- <activeProfiles>
- <activeProfile>jboss</activeProfile>
- </activeProfiles>
-
-</settings>
-
-
-
-Integration with CruiseControl
-------------------------------
-
-CruiseControl should do the following:
-
-* Run "mvn clean site" - will clean and run tests, and then prepare reports. In addition to unit tests, this project is set up to run FindBugs, PMD, jxr, and a bunch of other code analysis tools and provide a report in target/site/project-reports.html - which should be linked from the CruiseControl summary page.
-
Copied: pojo/tags/2.1.0.CR1/README-Maven.txt (from rev 4717, pojo/branches/2.1/README-Maven.txt)
===================================================================
--- pojo/tags/2.1.0.CR1/README-Maven.txt (rev 0)
+++ pojo/tags/2.1.0.CR1/README-Maven.txt 2007-11-03 02:27:34 UTC (rev 4726)
@@ -0,0 +1,104 @@
+Working with Maven
+------------------
+
+Requirements:
+
+* Java 5.0 and above
+* Maven 2.x
+
+Typical lifecycle phases
+------------------------
+
+Maven will create a target/ directory under the root for the creation of
+output at every stage.
+
+* mvn clean: cleans out any old builds and binaries
+
+* mvn compile: compiles java source code.
+
+* mvn test: runs the TestNG unit test suite on the compiled code. Will also compile the tests.
+
+* mvn package: packages the module as a jar file and builds the javadocs and user documentation from docbook sources.
+
+* mvn install: will install the artifacts in your local repo for use by other projects (such as JBoss Cache POJO edition which depends on JBoss Cache Core). Will also use Maven's assembly plugin to build ZIP files for download (in target/distribution)
+
+* mvn deploy: will build and deploy the project to the JBoss snapshots repository. Note that you should have your WebDAV username and password set up. (Deploys snapshots to http://snapshots.jboss.org/maven2/org/jboss/cache/). If you have a non-SNAPSHOT version number in your pom.xml, it will be deployed to the live releases repository (see below)
+
+
+Setting up your WebDAV username and password to deploy project snapshots
+------------------------------------------------------------------------
+
+You will also have to configure maven to use your username and password to access this repository. For this, you will have to modify the servers section of maven settings file ($MAVEN_HOME/conf/settings.xml, or ~/.m2/settings.xml). Something similar to the following should be added:
+
+<settings>
+
+...
+
+ <servers>
+...
+ <server>
+ <id>snapshots.jboss.org</id>
+ <username>webdav-user</username>
+ <password>webdav-pass</password>
+ </server>
+...
+
+ </servers>
+
+...
+
+</settings>
+
+Deploying a release to a live repository
+----------------------------------------
+
+Very simple. Make sure you have the version number in your pom.xml set to a non-SNAPSHOT version. Maven will pick up on this and deploy to your release repository rather than the snapshot repository.
+
+Sadly JBoss release repository cannot be accessed via WebDAV, as the snapshot repository can. So what you need to do is:
+
+1) Check out the release repository from Subversion (svn co https://svn.jboss.org/repos/repository.jboss.org/maven2)
+2) Add a property in ~/.m2/settings.xml to point to this 'local' copy of the repo. (See maven settings below)
+3) Update your project's pom.xml to reflect a non-SNAPSHOT version number
+4) Deploy your project (mvn clean deploy)
+5) Check in your 'local' copy of the repo checked out in (1), adding any new directories/files created by (4).
+
+Maven settings.xml
+------------------
+
+Working with the JBoss Cache source tree, I have configured my ~/.m2/settings.xml to look like:
+
+<settings>
+
+ <servers>
+ <server>
+ <id>snapshots.jboss.org</id>
+ <username>MY_JBOSS_ORG_USERNAME</username>
+ <password>WONT_TELL_YOU</password>
+ </server>
+ </servers>
+
+
+ <profiles>
+ <profile>
+ <id>jboss</id>
+ <properties>
+ <maven.repository.root>/Users/manik/Code/maven2</maven.repository.root>
+ </properties>
+ </profile>
+ </profiles>
+
+ <activeProfiles>
+ <activeProfile>jboss</activeProfile>
+ </activeProfiles>
+
+</settings>
+
+
+
+Integration with CruiseControl
+------------------------------
+
+CruiseControl should do the following:
+
+* Run "mvn clean site" - will clean and run tests, and then prepare reports. In addition to unit tests, this project is set up to run FindBugs, PMD, jxr, and a bunch of other code analysis tools and provide a report in target/site/project-reports.html - which should be linked from the CruiseControl summary page.
+
Copied: pojo/tags/2.1.0.CR1/assembly (from rev 4717, pojo/branches/2.1/assembly)
Deleted: pojo/tags/2.1.0.CR1/pom.xml
===================================================================
--- pojo/branches/2.1/pom.xml 2007-10-31 22:10:53 UTC (rev 4718)
+++ pojo/tags/2.1.0.CR1/pom.xml 2007-11-03 02:27:34 UTC (rev 4726)
@@ -1,287 +0,0 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <properties>
- <jbosscache-pojo-version>2.1.0.BETA1</jbosscache-pojo-version>
- <jboss.aop.version>2.0.0.beta1</jboss.aop.version>
- </properties>
- <parent>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-common-parent</artifactId>
- <version>1.1</version>
- </parent>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-pojo</artifactId>
- <version>${jbosscache-pojo-version}</version>
- <name>JBoss Cache - POJO Edition</name>
- <description>JBoss Cache - POJO Edition</description>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.jboss.aop</groupId>
- <artifactId>jboss-aop</artifactId>
- <version>${jboss.aop.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-core</artifactId>
- <version>2.1.0.BETA1</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-core</artifactId>
- <version>2.1.0.BETA1</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <!-- Hack AOP has broken deps -->
- <dependency>
- <groupId>org.jboss.microcontainer</groupId>
- <artifactId>jboss-container</artifactId>
- <version>2.0.0.Beta4</version>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.2-beta-1</version>
- <executions>
- <execution>
- <id>assemble</id>
- <phase>install</phase>
- <goals>
- <goal>attached</goal>
- </goals>
- <configuration>
- <descriptors>
- <descriptor>assembly/bin.xml</descriptor>
- <descriptor>assembly/doc.xml</descriptor>
- <descriptor>assembly/all.xml</descriptor>
- </descriptors>
- <finalName>${artifactId}-${jbosscache-pojo-version}</finalName>
- <outputDirectory>target/distribution</outputDirectory>
- <workDirectory>target/assembly/work</workDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <systemProperties>
- <property>
- <name>bind.address</name>
- <value>127.0.0.1</value>
- </property>
- <property>
- <name>java.net.preferIPv4Stack</name>
- <value>true</value>
- </property>
- <property>
- <name>jgroups.stack</name>
- <value>udp</value>
- </property>
- </systemProperties>
- <groups>functional</groups>
- <forkMode>always</forkMode>
- <argLine>-Djboss.aop.path=${basedir}/src/main/resources/META-INF/pojocache-aop.xml -javaagent:${settings.localRepository}/org/jboss/aop/jboss-aop/${jboss.aop.version}/jboss-aop-${jboss.aop.version}.jar</argLine>
- <!-- Warning, this does not work right on 2.4-SNAPSHOT, (see SUREFIRE-349) -->
- <!-- This seems to fail in some cases on 2.3 as well, disable for now -->
- <useSystemClassLoader>true</useSystemClassLoader>
- <redirectTestOutputToFile>false</redirectTestOutputToFile>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.jboss.maven.plugins</groupId>
- <artifactId>maven-jbossaop-plugin</artifactId>
- <version>2.0.0.beta1</version>
- <!-- HACK: AOP project and plugin has broken deps -->
- <dependencies>
- <dependency>
- <groupId>org.jboss.microcontainer</groupId>
- <artifactId>jboss-container</artifactId>
- <version>2.0.0.Beta4</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.0.4</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-core</artifactId>
- <version>2.1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <id>aopc</id>
- <phase>compile</phase>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <verbose>false</verbose>
- <aoppaths>
- <aoppath>${basedir}/src/main/resources/META-INF/pojocache-aop.xml</aoppath>
- </aoppaths>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <!-- the docbook generation plugin for the user guide -->
- <plugin>
- <groupId>org.jboss.maven.plugins</groupId>
- <artifactId>maven-jdocbook-plugin</artifactId>
- <version>2.0.0</version>
- <extensions>true</extensions>
- <dependencies>
- <dependency>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-doc-xslt-support</artifactId>
- <version>1.0</version>
- </dependency>
- </dependencies>
- <executions>
-
- <!-- The User Guide-->
- <execution>
- <id>userguide_en</id>
- <phase>package</phase>
- <goals>
- <goal>resources</goal>
- <goal>generate</goal>
- </goals>
- <configuration>
- <sourceDocumentName>master.xml</sourceDocumentName>
- <sourceDirectory>${basedir}/src/main/docbook/userguide/en</sourceDirectory>
- <imageResource>
- <directory>${basedir}/src/main/docbook/images</directory>
- </imageResource>
- <cssResource>
- <directory>${basedir}/src/main/docbook/css</directory>
- </cssResource>
- <targetDirectory>${basedir}/target/docbook/userguide_en</targetDirectory>
- <formats>
- <format>
- <formatName>pdf</formatName>
- <stylesheetResource>classpath:/standard/fopdf.xsl</stylesheetResource>
- <finalName>userguide_en.pdf</finalName>
- </format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/standard/html_chunk.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/standard/html.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- </formats>
- <options>
- <xincludeSupported>false</xincludeSupported>
- </options>
- </configuration>
- </execution>
-
- <!-- The Tutorial -->
- <execution>
- <id>tutorial_en</id>
- <phase>package</phase>
- <goals>
- <goal>resources</goal>
- <goal>generate</goal>
- </goals>
- <configuration>
- <sourceDocumentName>master.xml</sourceDocumentName>
- <sourceDirectory>${basedir}/src/main/docbook/tutorial/en</sourceDirectory>
- <imageResource>
- <directory>${basedir}/src/main/docbook/images</directory>
- </imageResource>
- <cssResource>
- <directory>${basedir}/src/main/docbook/css</directory>
- </cssResource>
- <targetDirectory>${basedir}/target/docbook/tutorial_en</targetDirectory>
- <formats>
- <format>
- <formatName>pdf</formatName>
- <stylesheetResource>classpath:/standard/fopdf.xsl</stylesheetResource>
- <finalName>tutorial_en.pdf</finalName>
- </format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/standard/html_chunk.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/standard/html.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- </formats>
- <options>
- <xincludeSupported>false</xincludeSupported>
- </options>
- </configuration>
- </execution>
-
- <!-- the FAQs -->
- <execution>
- <id>faq_en</id>
- <phase>package</phase>
- <goals>
- <goal>resources</goal>
- <goal>generate</goal>
- </goals>
- <configuration>
- <sourceDocumentName>master.xml</sourceDocumentName>
- <sourceDirectory>${basedir}/src/main/docbook/faq/en</sourceDirectory>
- <imageResource>
- <directory>${basedir}/src/main/docbook/images</directory>
- </imageResource>
- <cssResource>
- <directory>${basedir}/src/main/docbook/css</directory>
- </cssResource>
- <targetDirectory>${basedir}/target/docbook/faq_en</targetDirectory>
- <formats>
- <format>
- <formatName>pdf</formatName>
- <stylesheetResource>classpath:/standard/fopdf.xsl</stylesheetResource>
- <finalName>faq_en.pdf</finalName>
- </format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/standard/html_chunk.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/standard/html.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- </formats>
- <options>
- <xincludeSupported>false</xincludeSupported>
- </options>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <!-- basic JBoss repository so that the common parent POM in jbosscache-support can be found -->
- <repositories>
- <repository>
- <id>repository.jboss.org</id>
- <url>http://repository.jboss.org/maven2</url>
- </repository>
- </repositories>
-</project>
Copied: pojo/tags/2.1.0.CR1/pom.xml (from rev 4725, pojo/branches/2.1/pom.xml)
===================================================================
--- pojo/tags/2.1.0.CR1/pom.xml (rev 0)
+++ pojo/tags/2.1.0.CR1/pom.xml 2007-11-03 02:27:34 UTC (rev 4726)
@@ -0,0 +1,288 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <properties>
+ <jbosscache-pojo-version>2.1.0.CR1</jbosscache-pojo-version>
+ <jbosscache-core-version>2.1.0.CR1</jbosscache-core-version>
+ <jboss.aop.version>2.0.0.beta1</jboss.aop.version>
+ </properties>
+ <parent>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-common-parent</artifactId>
+ <version>1.1</version>
+ </parent>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-pojo</artifactId>
+ <version>${jbosscache-pojo-version}</version>
+ <name>JBoss Cache - POJO Edition</name>
+ <description>JBoss Cache - POJO Edition</description>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.aop</groupId>
+ <artifactId>jboss-aop</artifactId>
+ <version>${jboss.aop.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-core</artifactId>
+ <version>${jbosscache-core-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-core</artifactId>
+ <version>${jbosscache-core-version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <!-- Hack AOP has broken deps -->
+ <dependency>
+ <groupId>org.jboss.microcontainer</groupId>
+ <artifactId>jboss-container</artifactId>
+ <version>2.0.0.Beta4</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-1</version>
+ <executions>
+ <execution>
+ <id>assemble</id>
+ <phase>install</phase>
+ <goals>
+ <goal>attached</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>assembly/bin.xml</descriptor>
+ <descriptor>assembly/doc.xml</descriptor>
+ <descriptor>assembly/all.xml</descriptor>
+ </descriptors>
+ <finalName>${artifactId}-${jbosscache-pojo-version}</finalName>
+ <outputDirectory>target/distribution</outputDirectory>
+ <workDirectory>target/assembly/work</workDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>bind.address</name>
+ <value>127.0.0.1</value>
+ </property>
+ <property>
+ <name>java.net.preferIPv4Stack</name>
+ <value>true</value>
+ </property>
+ <property>
+ <name>jgroups.stack</name>
+ <value>udp</value>
+ </property>
+ </systemProperties>
+ <groups>functional</groups>
+ <forkMode>always</forkMode>
+ <argLine>-Djboss.aop.path=${basedir}/src/main/resources/META-INF/pojocache-aop.xml -javaagent:${settings.localRepository}/org/jboss/aop/jboss-aop/${jboss.aop.version}/jboss-aop-${jboss.aop.version}.jar</argLine>
+ <!-- Warning, this does not work right on 2.4-SNAPSHOT, (see SUREFIRE-349) -->
+ <!-- This seems to fail in some cases on 2.3 as well, disable for now -->
+ <useSystemClassLoader>true</useSystemClassLoader>
+ <redirectTestOutputToFile>false</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jbossaop-plugin</artifactId>
+ <version>2.0.0.beta1</version>
+ <!-- HACK: AOP project and plugin has broken deps -->
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.microcontainer</groupId>
+ <artifactId>jboss-container</artifactId>
+ <version>2.0.0.Beta4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-core</artifactId>
+ <version>${jbosscache-core-version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>aopc</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <verbose>false</verbose>
+ <aoppaths>
+ <aoppath>${basedir}/src/main/resources/META-INF/pojocache-aop.xml</aoppath>
+ </aoppaths>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- the docbook generation plugin for the user guide -->
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+ <version>2.0.0</version>
+ <extensions>true</extensions>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-doc-xslt-support</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ <executions>
+
+ <!-- The User Guide-->
+ <execution>
+ <id>userguide_en</id>
+ <phase>package</phase>
+ <goals>
+ <goal>resources</goal>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <sourceDocumentName>master.xml</sourceDocumentName>
+ <sourceDirectory>${basedir}/src/main/docbook/userguide/en</sourceDirectory>
+ <imageResource>
+ <directory>${basedir}/src/main/docbook/images</directory>
+ </imageResource>
+ <cssResource>
+ <directory>${basedir}/src/main/docbook/css</directory>
+ </cssResource>
+ <targetDirectory>${basedir}/target/docbook/userguide_en</targetDirectory>
+ <formats>
+ <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath:/standard/fopdf.xsl</stylesheetResource>
+ <finalName>userguide_en.pdf</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/standard/html_chunk.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/standard/html.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>false</xincludeSupported>
+ </options>
+ </configuration>
+ </execution>
+
+ <!-- The Tutorial -->
+ <execution>
+ <id>tutorial_en</id>
+ <phase>package</phase>
+ <goals>
+ <goal>resources</goal>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <sourceDocumentName>master.xml</sourceDocumentName>
+ <sourceDirectory>${basedir}/src/main/docbook/tutorial/en</sourceDirectory>
+ <imageResource>
+ <directory>${basedir}/src/main/docbook/images</directory>
+ </imageResource>
+ <cssResource>
+ <directory>${basedir}/src/main/docbook/css</directory>
+ </cssResource>
+ <targetDirectory>${basedir}/target/docbook/tutorial_en</targetDirectory>
+ <formats>
+ <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath:/standard/fopdf.xsl</stylesheetResource>
+ <finalName>tutorial_en.pdf</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/standard/html_chunk.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/standard/html.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>false</xincludeSupported>
+ </options>
+ </configuration>
+ </execution>
+
+ <!-- the FAQs -->
+ <execution>
+ <id>faq_en</id>
+ <phase>package</phase>
+ <goals>
+ <goal>resources</goal>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <sourceDocumentName>master.xml</sourceDocumentName>
+ <sourceDirectory>${basedir}/src/main/docbook/faq/en</sourceDirectory>
+ <imageResource>
+ <directory>${basedir}/src/main/docbook/images</directory>
+ </imageResource>
+ <cssResource>
+ <directory>${basedir}/src/main/docbook/css</directory>
+ </cssResource>
+ <targetDirectory>${basedir}/target/docbook/faq_en</targetDirectory>
+ <formats>
+ <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath:/standard/fopdf.xsl</stylesheetResource>
+ <finalName>faq_en.pdf</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/standard/html_chunk.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/standard/html.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>false</xincludeSupported>
+ </options>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!-- basic JBoss repository so that the common parent POM in jbosscache-support can be found -->
+ <repositories>
+ <repository>
+ <id>repository.jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ </repositories>
+</project>
Copied: pojo/tags/2.1.0.CR1/src (from rev 4717, pojo/branches/2.1/src)
17 years, 2 months
JBoss Cache SVN: r4725 - pojo/branches/2.1.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2007-11-02 18:37:54 -0400 (Fri, 02 Nov 2007)
New Revision: 4725
Modified:
pojo/branches/2.1/pom.xml
Log:
Prepare for tag
Modified: pojo/branches/2.1/pom.xml
===================================================================
--- pojo/branches/2.1/pom.xml 2007-11-02 13:15:27 UTC (rev 4724)
+++ pojo/branches/2.1/pom.xml 2007-11-02 22:37:54 UTC (rev 4725)
@@ -4,7 +4,8 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
- <jbosscache-pojo-version>2.1.0.BETA1</jbosscache-pojo-version>
+ <jbosscache-pojo-version>2.1.0.CR1</jbosscache-pojo-version>
+ <jbosscache-core-version>2.1.0.CR1</jbosscache-core-version>
<jboss.aop.version>2.0.0.beta1</jboss.aop.version>
</properties>
<parent>
@@ -27,12 +28,12 @@
<dependency>
<groupId>org.jboss.cache</groupId>
<artifactId>jbosscache-core</artifactId>
- <version>2.1.0.BETA1</version>
+ <version>${jbosscache-core-version}</version>
</dependency>
<dependency>
<groupId>org.jboss.cache</groupId>
<artifactId>jbosscache-core</artifactId>
- <version>2.1.0.BETA1</version>
+ <version>${jbosscache-core-version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
@@ -116,7 +117,7 @@
<dependency>
<groupId>org.jboss.cache</groupId>
<artifactId>jbosscache-core</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>${jbosscache-core-version}</version>
</dependency>
</dependencies>
<executions>
17 years, 2 months
JBoss Cache SVN: r4724 - core/trunk/src/test/java/org/jboss/cache/loader.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2007-11-02 09:15:27 -0400 (Fri, 02 Nov 2007)
New Revision: 4724
Added:
core/trunk/src/test/java/org/jboss/cache/loader/JDBCCacheLoaderConnectionTest.java
Log:
added test to check connections being closed
Added: core/trunk/src/test/java/org/jboss/cache/loader/JDBCCacheLoaderConnectionTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/JDBCCacheLoaderConnectionTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/loader/JDBCCacheLoaderConnectionTest.java 2007-11-02 13:15:27 UTC (rev 4724)
@@ -0,0 +1,73 @@
+package org.jboss.cache.loader;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheImpl;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.sql.Connection;
+
+/**
+ * To test the closing of JDBC connections
+ */
+@Test (groups = {"functional"})
+public class JDBCCacheLoaderConnectionTest extends AbstractCacheLoaderTestBase
+{
+ private Cache cache;
+
+ @BeforeMethod
+ public void setUp() throws Exception
+ {
+ String props = " cache.jdbc.table.name=jbosscache_engine_cache\n" +
+ " cache.jdbc.table.create=true\n" +
+ " cache.jdbc.table.drop=true\n" +
+ " cache.jdbc.table.primarykey=jbosscache_engine_cache_pk\n" +
+ " cache.jdbc.fqn.column=fqn\n" +
+ " cache.jdbc.fqn.type=varchar(255)\n" +
+ " cache.jdbc.node.column=node\n" +
+ " cache.jdbc.node.type=blob\n" +
+ " cache.jdbc.parent.column=parent\n" +
+ " cache.jdbc.sql-concat=1 || 2\n" +
+ " cache.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver\n" +
+ " cache.jdbc.url=jdbc:derby:jbossdb;create=true\n" +
+ " cache.jdbc.user=user1\n" +
+ " cache.jdbc.password=user1";
+
+ cache = DefaultCacheFactory.getInstance().createCache(false);
+ cache.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", JDBCCacheLoader.class.getName(), props, false, false, true, false));
+ cache.start();
+ }
+
+ @AfterMethod
+ public void tearDown()
+ {
+ cache.stop();
+ }
+
+ public void testConnectionRelease() throws Exception
+ {
+ cache.removeNode(Fqn.fromString("C"));
+ for (int i = 0; i < 100; i++)
+ {
+ cache.put(new Fqn("C", Integer.toString(i)), "Blah", Integer.toString(i));
+ System.out.println("added "+i+" dummy node to Jboss cache.");
+ }
+
+ assertConnectionsClosed();
+ }
+
+ private void assertConnectionsClosed() throws Exception
+ {
+ JDBCCacheLoader loader = (JDBCCacheLoader) ((CacheImpl) cache).getCacheLoader();
+ NonManagedConnectionFactory cf = (NonManagedConnectionFactory) loader.cf;
+ Connection conn = cf.connection.get();
+ if (conn != null)
+ {
+ // make sure it is closed/released!
+ assert conn.isClosed();
+ }
+ }
+}
17 years, 2 months
JBoss Cache SVN: r4723 - core/trunk/src/main/java/org/jboss/cache/loader.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2007-11-02 09:12:04 -0400 (Fri, 02 Nov 2007)
New Revision: 4723
Modified:
core/trunk/src/main/java/org/jboss/cache/loader/NonManagedConnectionFactory.java
Log:
Genericised thread local
Modified: core/trunk/src/main/java/org/jboss/cache/loader/NonManagedConnectionFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/NonManagedConnectionFactory.java 2007-11-01 17:04:24 UTC (rev 4722)
+++ core/trunk/src/main/java/org/jboss/cache/loader/NonManagedConnectionFactory.java 2007-11-02 13:12:04 UTC (rev 4723)
@@ -23,7 +23,7 @@
{
private static final Log log = LogFactory.getLog(NonManagedConnectionFactory.class);
- private static final ThreadLocal connection = new ThreadLocal();
+ static final ThreadLocal<Connection> connection = new ThreadLocal<Connection>();
private String url;
private String usr;
@@ -71,7 +71,7 @@
public Connection getConnection()
{
- Connection con = (Connection) connection.get();
+ Connection con = connection.get();
if (con == null)
{
@@ -101,7 +101,7 @@
public void commit(Object tx)
{
- Connection con = (Connection) connection.get();
+ Connection con = connection.get();
if (con == null)
{
throw new IllegalStateException("Failed to commit: thread is not associated with the connection!");
@@ -127,7 +127,7 @@
public void rollback(Object tx)
{
- Connection con = (Connection) connection.get();
+ Connection con = connection.get();
if (con == null)
{
// todo: prepare was not called. why is rollback called?
17 years, 2 months