JBoss Cache SVN: r7656 - in searchable/trunk: src/main/java/org/jboss/cache/search and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: navssurtani
Date: 2009-02-06 05:03:13 -0500 (Fri, 06 Feb 2009)
New Revision: 7656
Added:
searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryPojoImpl.java
searchable/trunk/src/main/java/org/jboss/cache/search/EntityId.java
searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityId.java
searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityLoader.java
searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCachePojoImpl.java
Modified:
searchable/trunk/
searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityId.java
searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityLoader.java
searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryImpl.java
searchable/trunk/src/main/java/org/jboss/cache/search/QueryResultIteratorImpl.java
searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheFactory.java
searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheImpl.java
searchable/trunk/src/main/java/org/jboss/cache/search/SearchablePojoListener.java
Log:
Property changes on: searchable/trunk
___________________________________________________________________
Name: svn:ignore
+ jbosscache-searchable.iws
jbosscache-searchable.iml
jbosscache-searchable.ipr
test-output
out
org.jboss.cache.search.test.Person
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityId.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityId.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityId.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -30,48 +30,23 @@
* <p/>
* @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
*/
-public class CacheEntityId
+public class CacheEntityId extends PojoEntityId
{
- Fqn fqn;
String key;
- String documentId;
public CacheEntityId(String documentId)
{
- if(documentId == null) throw new NullPointerException("documentId is null");
- this.documentId = documentId;
+ super(documentId);
}
public CacheEntityId(Fqn fqn, String key)
{
- if(fqn == null) throw new NullPointerException("Fqn is null");
+ super(fqn);
if(key == null) throw new NullPointerException("Key is null");
- this.fqn = fqn;
this.key = key;
}
/**
- * Gets the Fqn from the instance of CacheEntityId.
- *
- * @return Fqn from the instance of CacheEntityId.
- */
-
- public Fqn getFqn()
- {
- if (fqn != null) return fqn;
- if (documentId != null)
- {
- fqn = Transformer.getFqn(documentId);
- return fqn;
- }
-
- if(documentId == null)
- throw new IllegalArgumentException("docId is null");
-
- throw new IllegalArgumentException("Fqn is null");
- }
-
- /**
* Gets the key from the instance of CacheEntityId.
*
* @return Key from the instance of CacheEntityId.
@@ -105,4 +80,9 @@
return Transformer.generateId(fqn, key);
}
+
+ public Fqn getFqn()
+ {
+ throw new RuntimeException("implement me");
+ }
}
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityLoader.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityLoader.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/CacheEntityLoader.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -50,29 +50,35 @@
* @return List of objects loaded from the cache. The list returned will be exactly the same size as the ids list passed in.
* @throws NullPointerException if ids is null.
*/
- public List<Object> load(List<CacheEntityId> ids)
+ public List<Object> load(List<EntityId> ids)
{
if (ids == null) throw new NullPointerException("ids are null");
List<Object> retVal = new ArrayList<Object>(ids.size());
- for (CacheEntityId id: ids)
+ for (EntityId id: ids)
{
- retVal.add( cache.get(id.getFqn(), id.getKey()) );
+ retVal.add( loadFromCache(id) );
if(log.isTraceEnabled()) log.trace("Created list of return values. Size is " + retVal.size() );
}
return retVal;
}
+ protected Object loadFromCache(EntityId id)
+ {
+ CacheEntityId cei = (CacheEntityId) id;
+ return cache.get(cei.getFqn(), cei.getKey());
+ }
+
/**
* Takes a list of entity ids and gets them from the cache.
* @param id cache entity id to look up in the cache.
* @return the object from the cache, or null if one cannot be found.
* @throws NullPointerException if ids is null.
*/
- public Object load(CacheEntityId id)
+ public Object load(EntityId id)
{
if (id == null) throw new NullPointerException("id is null");
- return cache.get(id.getFqn(), id.getKey());
+ return loadFromCache(id);
}
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryImpl.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryImpl.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryImpl.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -43,6 +43,7 @@
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.transform.ResultTransformer;
import org.jboss.cache.Cache;
+import org.jboss.cache.pojo.PojoCache;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -63,36 +64,43 @@
public class CacheQueryImpl implements CacheQuery
{
// private Cache cache; - Removed on 11/07/2008, cache is assigned but never used. Hence removed.
- private Class[] classes;
private Sort sort;
private Filter filter;
private Map<String, FullTextFilterImpl> filterDefinitions;
- private SearchFactoryImplementor searchFactory;
private Integer firstResult;
private Integer resultSize;
private Integer maxResults;
private static final Log log = LogFactory.getLog(CacheQueryImpl.class);
private boolean needClassFilterClause;
- private Query luceneQuery;
private String[] indexProjection;
private ResultTransformer resultTransformer;
CacheEntityLoader entityLoader;
- private Set<Class<?>> targetedEntities;
private Set<Class<?>> classesAndSubclasses;
private Set<String> idFieldNames;
private boolean allowFieldSelectionInProjection = true;
+ // Protected fields for CacheQueryPojoImpl to see.
+ protected Query luceneQuery;
+ protected SearchFactoryImplementor searchFactory;
+ protected Set<Class<?>> targetedEntities;
+ protected Cache cache;
+ protected Class[] classes;
+
+
+
+
public CacheQueryImpl(Query luceneQuery, SearchFactoryImplementor searchFactory, Cache cache, Class... classes)
{
this.luceneQuery = luceneQuery;
-// this.cache = cache;
+ this.cache = cache;
entityLoader = new CacheEntityLoader(cache);
this.searchFactory = searchFactory;
- this.targetedEntities = this.searchFactory.getIndexedTypesPolymorphic( classes );
+ this.targetedEntities = this.searchFactory.getIndexedTypesPolymorphic(classes);
this.classes = classes;
}
+
/**
* Takes in a lucene filter and sets it to the filter field in the class.
*
@@ -224,7 +232,7 @@
public QueryResultIterator iterator(int fetchSize) throws HibernateException
{
- List<CacheEntityId> ids = null;
+ List<EntityId> ids = null;
IndexSearcher searcher = buildSearcher(searchFactory);
if (searcher == null)
{
@@ -237,13 +245,13 @@
int first = first();
int max = max(first, queryHits.totalHits);
int size = max - first + 1 < 0 ? 0 : max - first + 1;
- ids = new ArrayList<CacheEntityId>(size);
+ ids = new ArrayList<EntityId>(size);
DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
for (int index = first; index <= max; index++)
{
String documentId = (String) extractor.extract(index).id;
- CacheEntityId id = new CacheEntityId(documentId);
+ EntityId id = createCacheEntityId(documentId);
ids.add(id);
}
@@ -315,13 +323,13 @@
int size = max - first + 1 < 0 ? 0 : max - first + 1;
- List<CacheEntityId> ids = new ArrayList<CacheEntityId>(size);
DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
+ List<EntityId> ids = new ArrayList<EntityId>(size);
for (int index = first; index <= max; index++)
{
String documentId = (String) extractor.extract(index).id;
- CacheEntityId id = new CacheEntityId(documentId);
+ EntityId id = createCacheEntityId(documentId);
ids.add(id);
}
@@ -350,7 +358,12 @@
}
+ protected EntityId createCacheEntityId(String docId)
+ {
+ return new CacheEntityId(docId);
+ }
+
private int max(int first, int totalHits)
{
if (maxResults == null)
@@ -544,7 +557,6 @@
}
-
private org.apache.lucene.search.Query filterQueryByClasses(org.apache.lucene.search.Query luceneQuery)
{
if (!needClassFilterClause)
Added: searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryPojoImpl.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryPojoImpl.java (rev 0)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/CacheQueryPojoImpl.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -0,0 +1,33 @@
+package org.jboss.cache.search;
+
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.Cache;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.apache.lucene.search.Query;
+
+/**
+ * @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
+ */
+public class CacheQueryPojoImpl extends CacheQueryImpl
+{
+
+ private PojoCache pojo;
+
+ public CacheQueryPojoImpl(Query luceneQuery, SearchFactoryImplementor searchFactory, PojoCache pojo, Class... classes)
+ {
+ super (luceneQuery, searchFactory, pojo.getCache(), classes);
+
+ this.pojo = pojo;
+
+ // Create a pojo entity loader instead of a cache entity loader since we are dealing with a pojo cache
+ entityLoader = new PojoEntityLoader(pojo);
+
+ }
+
+ protected EntityId createCacheEntityId(String docId)
+ {
+ return new PojoEntityId(docId);
+ }
+
+
+}
Added: searchable/trunk/src/main/java/org/jboss/cache/search/EntityId.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/EntityId.java (rev 0)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/EntityId.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -0,0 +1,13 @@
+package org.jboss.cache.search;
+
+import org.jboss.cache.Fqn;
+
+/**
+ * @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
+ */
+public interface EntityId
+{
+ Fqn getFqn();
+
+ String getDocumentId() throws InvalidKeyException;
+}
Added: searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityId.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityId.java (rev 0)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityId.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -0,0 +1,65 @@
+package org.jboss.cache.search;
+
+import org.jboss.cache.Fqn;
+
+/**
+ * This class is used to get fqns, keys and documentId's by calling methods on {@link org.jboss.cache.search.Transformer}
+ * <p/>
+ *
+ * @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
+ */
+public class PojoEntityId implements EntityId
+{
+ // Contains documentId and fqn fields. Subclassed by CacheEntityId.
+ protected String documentId;
+ protected Fqn fqn;
+
+ public PojoEntityId (Fqn fqn)
+ {
+ if (fqn == null) throw new NullPointerException("Fqn is null.");
+ this.fqn = fqn;
+ documentId = fqn.toString();
+
+ }
+
+ public PojoEntityId (String documentId)
+ {
+ if (documentId == null) throw new NullPointerException("doc ID is null.");
+ this.documentId = documentId;
+ }
+
+ /**
+ * Gets the Fqn from the instance of CacheEntityId.
+ *
+ * @return Fqn from the instance of CacheEntityId.
+ */
+
+ public Fqn getFqn()
+ {
+ if (fqn != null) return fqn;
+ if (documentId != null)
+ {
+ fqn = Fqn.fromString(documentId);
+ return fqn;
+ }
+ throw new IllegalArgumentException("docId is null");
+ }
+
+ /**
+ * Gets a documentId String from an Fqn and key combination.
+ *
+ * @return documentId String.
+ */
+
+
+ public String getDocumentId() throws InvalidKeyException
+ {
+ if (fqn == null)
+ {
+ throw new IllegalArgumentException("Either your key or fqn is null. Please check again.");
+ }
+
+ return fqn.toString();
+ }
+
+}
Added: searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityLoader.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityLoader.java (rev 0)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/PojoEntityLoader.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -0,0 +1,23 @@
+package org.jboss.cache.search;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.pojo.PojoCache;
+
+/**
+ * @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
+ */
+public class PojoEntityLoader extends CacheEntityLoader
+{
+ PojoCache pojoCache;
+
+ public PojoEntityLoader(PojoCache pojoCache)
+ {
+ super(pojoCache.getCache());
+ this.pojoCache = pojoCache;
+ }
+
+ protected Object loadFromCache(CacheEntityId id)
+ {
+ return pojoCache.find(id.getFqn());
+ }
+}
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/QueryResultIteratorImpl.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/QueryResultIteratorImpl.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/QueryResultIteratorImpl.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -42,7 +42,7 @@
{
private int index = 0;
//private final int size;
- private List<CacheEntityId> idList;
+ private List<EntityId> idList;
private CacheEntityLoader entityLoader;
private int lowerLimit = 0;
private int upperLimit = 0;
@@ -52,7 +52,7 @@
private static final Log log = LogFactory.getLog(QueryResultIteratorImpl.class);
- public QueryResultIteratorImpl(List<CacheEntityId> idList, CacheEntityLoader entityLoader, int fetchSize)
+ public QueryResultIteratorImpl(List<EntityId> idList, CacheEntityLoader entityLoader, int fetchSize)
{
if (fetchSize < 1)
{
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheFactory.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheFactory.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheFactory.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -119,11 +119,9 @@
{
System.out.println("create searchable cache called with pojo cache");
- //TODO: Ask Manik and/or Jason if there is a way to directly check if the pojo cache is started or not
validateClasses(classes);
Cache coreCache = pojo.getCache();
-
if (coreCache.getCacheStatus() != CacheStatus.STARTED)
{
if (log.isInfoEnabled()) log.info("Cache not started. Starting cache first.");
@@ -146,7 +144,7 @@
pojo.addListener(pojoListener);
pojo.getCache().addCacheListener(pojoListener);
- SearchableCache sc = new SearchableCacheImpl(coreCache, searchFactory);
+ SearchableCache sc = new SearchableCachePojoImpl(pojo, searchFactory);
return sc;
}
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheImpl.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheImpl.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCacheImpl.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -32,6 +32,7 @@
import org.jboss.cache.Node;
import org.jboss.cache.NodeNotExistsException;
import org.jboss.cache.Region;
+import org.jboss.cache.pojo.PojoCache;
import org.jboss.cache.interceptors.base.CommandInterceptor;
import org.jboss.cache.config.Configuration;
import org.jgroups.Address;
@@ -49,11 +50,12 @@
public class SearchableCacheImpl<K, V> implements SearchableCache<K, V>
{
// this is the ACTUAL cache. that does all the work.
- private Cache<K, V> cache;
+ // protected fields for Pojo subclass
+ protected Cache<K, V> cache;
+ protected SearchFactoryImplementor searchFactory;
- private SearchFactoryImplementor searchFactory;
-
+
public SearchableCacheImpl(Cache<K, V> cache, SearchFactoryImplementor searchFactory)
{
if (cache == null) throw new NullPointerException("Cache is null");
@@ -62,6 +64,8 @@
this.searchFactory = searchFactory;
}
+
+
/**
* Creates a CacheQuery object from a Lucene Query and a class array.
*
Added: searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCachePojoImpl.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCachePojoImpl.java (rev 0)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/SearchableCachePojoImpl.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -0,0 +1,34 @@
+package org.jboss.cache.search;
+
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.Cache;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.apache.lucene.search.Query;
+
+/**
+ * @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
+ */
+public class SearchableCachePojoImpl extends SearchableCacheImpl
+{
+
+ private PojoCache pojo;
+
+ /**
+ * Pojo cache implementation constructor.
+ *
+ * @param pojo
+ * @param searchFactory
+ */
+
+ public SearchableCachePojoImpl(PojoCache pojo, SearchFactoryImplementor searchFactory)
+ {
+ super(pojo.getCache(), searchFactory);
+ if (pojo == null) throw new NullPointerException("pojo is null");
+ this.pojo = pojo;
+ }
+
+ public CacheQuery createQuery(Query luceneQuery, Class... classes)
+ {
+ return new CacheQueryPojoImpl(luceneQuery, searchFactory, pojo, classes);
+ }
+}
Modified: searchable/trunk/src/main/java/org/jboss/cache/search/SearchablePojoListener.java
===================================================================
--- searchable/trunk/src/main/java/org/jboss/cache/search/SearchablePojoListener.java 2009-02-05 17:34:33 UTC (rev 7655)
+++ searchable/trunk/src/main/java/org/jboss/cache/search/SearchablePojoListener.java 2009-02-06 10:03:13 UTC (rev 7656)
@@ -69,15 +69,15 @@
{
if (!nme.isPre()) return;
Fqn f = nme.getFqn();
- if(log.isDebugEnabled()) log.debug("Node modified called for Fqn " + f);
+ System.out.println("Node modified called for Fqn " + f);
if (InternalHelper.isInternalNode(f))
{
- if(log.isDebugEnabled()) log.debug("Is internal and I dont care");
+ System.out.println("Is internal and I dont care");
}
else
{
savedFqn.set(f);
- if(log.isDebugEnabled()) log.debug("Saved Fqn to ThreadLocal.");
+ System.out.println("Saved Fqn to ThreadLocal.");
}
}
@@ -86,15 +86,15 @@
{
if (!nce.isPre()) return;
Fqn f = nce.getFqn();
- if(log.isDebugEnabled()) log.debug("Node kreated called for Fqn " + f);
+ System.out.println("Node kreated called for Fqn " + f);
if (InternalHelper.isInternalNode(f))
{
- if(log.isDebugEnabled()) log.debug("Is internal and I dont care");
+ System.out.println("Is internal and I dont care");
}
else
{
savedFqn.set(f);
- if(log.isDebugEnabled()) log.debug("savedFqn.set() called");
+ System.out.println("savedFqn.set() called");
}
}
15 years, 10 months
JBoss Cache SVN: r7655 - core/branches/flat/src/main/java/org/horizon/util.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-05 12:34:33 -0500 (Thu, 05 Feb 2009)
New Revision: 7655
Modified:
core/branches/flat/src/main/java/org/horizon/util/FileLookup.java
Log:
Fixed deprecation
Modified: core/branches/flat/src/main/java/org/horizon/util/FileLookup.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/FileLookup.java 2009-02-05 13:00:20 UTC (rev 7654)
+++ core/branches/flat/src/main/java/org/horizon/util/FileLookup.java 2009-02-05 17:34:33 UTC (rev 7655)
@@ -83,7 +83,7 @@
if (u == null) {
File f = new File(filename);
if (f.exists()) try {
- u = f.toURL();
+ u = f.toURI().toURL();
}
catch (MalformedURLException e) {
// what do we do here?
15 years, 10 months
JBoss Cache SVN: r7654 - in core/trunk: src/main/java/org/jboss/cache and 10 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-05 08:00:20 -0500 (Thu, 05 Feb 2009)
New Revision: 7654
Added:
core/trunk/src/test/java/org/jboss/cache/jmx/JmxManualTest.java
Modified:
core/trunk/pom.xml
core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java
core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/Version.java
core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java
core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java
core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java
core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java
core/trunk/src/main/java/org/jboss/cache/util/CachePrinter.java
core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java
core/trunk/src/test/java/org/jboss/cache/config/parsing/SampleConfigFilesCorrectnessTest.java
core/trunk/src/test/java/org/jboss/cache/jmx/deprecated/CacheJmxWrapperTest.java
core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java
Log:
re-introduced fixes from rev 7641, 7639 and 7636
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/pom.xml 2009-02-05 13:00:20 UTC (rev 7654)
@@ -2,501 +2,504 @@
<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-core-version>3.0.3-SNAPSHOT</jbosscache-core-version>
- <!-- By default only run tests in the "unit" group -->
- <defaultTestGroup>unit</defaultTestGroup>
- <!-- By default only generate Javadocs when we install the module. -->
- <javadocPhase>install</javadocPhase>
- </properties>
+ <modelVersion>4.0.0</modelVersion>
+ <properties>
+ <jbosscache-core-version>3.1.0-SNAPSHOT</jbosscache-core-version>
+ <!-- By default only run tests in the "unit" group -->
+ <defaultTestGroup>unit</defaultTestGroup>
+ <!-- By default only generate Javadocs when we install the module. -->
+ <javadocPhase>install</javadocPhase>
+ </properties>
- <parent>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-common-parent</artifactId>
- <version>1.5</version>
- </parent>
- <groupId>org.jboss.cache</groupId>
- <artifactId>jbosscache-core</artifactId>
- <version>${jbosscache-core-version}</version>
- <name>JBoss Cache - Core Edition</name>
- <description>JBoss Cache - Core Edition</description>
- <url>http://www.jbosscache.org</url>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>jgroups</groupId>
- <artifactId>jgroups</artifactId>
- <version>2.6.7.GA</version>
- </dependency>
+ <parent>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-common-parent</artifactId>
+ <version>1.5</version>
+ </parent>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-core</artifactId>
+ <version>${jbosscache-core-version}</version>
+ <name>JBoss Cache - Core Edition</name>
+ <description>JBoss Cache - Core Edition</description>
+ <url>http://www.jbosscache.org</url>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>jgroups</groupId>
+ <artifactId>jgroups</artifactId>
+ <version>2.6.7.GA</version>
+ </dependency>
- <!--
- For the JTA 1.1 API; consuming projects can safely
- exclude this and replace with any valid source of this API, such as a Java EE app server.
- -->
- <dependency>
- <groupId>javax.transaction</groupId>
- <artifactId>jta</artifactId>
- <version>1.1</version>
- </dependency>
+ <!--
+ For the JTA 1.1 API; consuming projects can safely
+ exclude this and replace with any valid source of this API, such as a Java EE app server.
+ -->
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ <version>1.1</version>
+ </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1.1</version>
- </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1.1</version>
+ </dependency>
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-common-core</artifactId>
- <version>2.2.10.GA</version>
- </dependency>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
+ <version>2.2.10.GA</version>
+ </dependency>
- <!-- optional dependencies -->
- <dependency>
- <groupId>jdbm</groupId>
- <artifactId>jdbm</artifactId>
- <version>1.0</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>c3p0</groupId>
- <artifactId>c3p0</artifactId>
- <version>0.9.1.2</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>sleepycat</groupId>
- <artifactId>je</artifactId>
- <version>3.2.43</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>net.jcip</groupId>
- <artifactId>jcip-annotations</artifactId>
- <version>1.0</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>net.noderunner</groupId>
- <artifactId>amazon-s3</artifactId>
- <version>1.0.0.0</version>
- <optional>true</optional>
- </dependency>
+ <!-- optional dependencies -->
+ <dependency>
+ <groupId>jdbm</groupId>
+ <artifactId>jdbm</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>c3p0</groupId>
+ <artifactId>c3p0</artifactId>
+ <version>0.9.1.2</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>sleepycat</groupId>
+ <artifactId>je</artifactId>
+ <version>3.2.43</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>net.jcip</groupId>
+ <artifactId>jcip-annotations</artifactId>
+ <version>1.0</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>net.noderunner</groupId>
+ <artifactId>amazon-s3</artifactId>
+ <version>1.0.0.0</version>
+ <optional>true</optional>
+ </dependency>
- <!-- test dependencies -->
- <dependency>
- <groupId>hsqldb</groupId>
- <artifactId>hsqldb</artifactId>
- <version>1.8.0.7</version>
- <scope>test</scope>
- </dependency>
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>1.8.0.7</version>
+ <scope>test</scope>
+ </dependency>
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <version>2.4</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>jboss.jbossts</groupId>
- <artifactId>jbossjta</artifactId>
- <version>4.4.0.GA</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>beanshell</groupId>
- <artifactId>bsh</artifactId>
- <version>2.0b4</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>net.noderunner</groupId>
- <artifactId>http</artifactId>
- <version>1.0</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- <scope>test</scope>
- </dependency>
- <!-- 5.8 is needed for proper parallel test execution -->
- <dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>5.8</version>
- <scope>test</scope>
- <classifier>jdk15</classifier>
- </dependency>
- </dependencies>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>2.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>jboss.jbossts</groupId>
+ <artifactId>jbossjta</artifactId>
+ <version>4.4.0.GA</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>beanshell</groupId>
+ <artifactId>bsh</artifactId>
+ <version>2.0b4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.noderunner</groupId>
+ <artifactId>http</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- 5.8 is needed for proper parallel test execution -->
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.8</version>
+ <scope>test</scope>
+ <classifier>jdk15</classifier>
+ </dependency>
+ </dependencies>
- <build>
- <plugins>
- <!-- ensure parallel test execution -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.4.3-JBOSS</version>
- <configuration>
- <parallel>tests</parallel>
- <threadCount>10</threadCount>
- <forkMode>none</forkMode>
- <systemProperties>
- <property>
- <name>jgroups.stack</name>
- <value>${protocol.stack}</value>
- </property>
- </systemProperties>
- <trimStackTrace>false</trimStackTrace>
- <properties>
- <property>
- <name>listener</name>
- <value>org.jboss.cache.util.UnitTestTestNGListener</value>
- </property>
- </properties>
- </configuration>
- </plugin>
- <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>
- <descriptor>assembly/src.xml</descriptor>
- </descriptors>
- <finalName>${artifactId}-${jbosscache-core-version}</finalName>
- <outputDirectory>target/distribution</outputDirectory>
- <workDirectory>target/assembly/work</workDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
- <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
- <mainClass>org.jboss.cache.Version</mainClass>
- </manifest>
- </archive>
- </configuration>
- <executions>
- <execution>
- <id>build-test-jar</id>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <configuration>
- <archive>
- <manifest>
- <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
- <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
- </manifest>
- </archive>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-report-plugin</artifactId>
- <version>2.4.3-JBOSS</version>
- </plugin>
- </plugins>
- </reporting>
-
- <!-- 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>
- <repository>
- <id>snapshots.jboss.org</id>
- <url>http://snapshots.jboss.org/maven2</url>
- </repository>
- <!-- For Amazon S3 artifacts -->
- <repository>
- <id>e-xml.sourceforge.net</id>
- <url>http://e-xml.sourceforge.net/maven2/repository</url>
- </repository>
- </repositories>
-
- <profiles>
- <profile>
- <!-- This testMoreState generates Javadocs and the UserGuide, FAQs and Tutorial in the "package" phase. -->
- <id>Docs</id>
- <activation>
- <activeByDefault>false</activeByDefault>
- </activation>
- <properties>
- <!-- override to generate javadocs in the "package" phase -->
- <javadocPhase>package</javadocPhase>
- </properties>
- <build>
- <plugins>
- <!-- 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</groupId>
- <artifactId>jbossorg-docbook-xslt</artifactId>
- <version>1.1.0</version>
- </dependency>
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jbossorg-jdocbook-style</artifactId>
- <version>1.1.0</version>
- <type>jdocbook-style</type>
- </dependency>
- </dependencies>
- <executions>
-
- <!-- The User Guide-->
- <execution>
- <id>userguide_en</id>
- <phase>package</phase>
+ <build>
+ <plugins>
+ <!-- ensure parallel test execution -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.3-JBOSS</version>
+ <configuration>
+ <parallel>tests</parallel>
+ <threadCount>10</threadCount>
+ <forkMode>none</forkMode>
+ <systemProperties>
+ <property>
+ <name>jgroups.stack</name>
+ <value>${protocol.stack}</value>
+ </property>
+ </systemProperties>
+ <trimStackTrace>false</trimStackTrace>
+ <properties>
+ <property>
+ <name>listener</name>
+ <value>org.jboss.cache.util.UnitTestTestNGListener</value>
+ </property>
+ </properties>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-1</version>
+ <executions>
+ <execution>
+ <id>assemble</id>
+ <phase>install</phase>
<goals>
- <goal>resources</goal>
- <goal>generate</goal>
+ <goal>attached</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:/xslt/org/jboss/pdf.xsl</stylesheetResource>
- <finalName>userguide_en.pdf</finalName>
- </format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- </formats>
- <options>
- <xincludeSupported>false</xincludeSupported>
- </options>
+ <descriptors>
+ <descriptor>assembly/bin.xml</descriptor>
+ <descriptor>assembly/doc.xml</descriptor>
+ <descriptor>assembly/all.xml</descriptor>
+ <descriptor>assembly/src.xml</descriptor>
+ </descriptors>
+ <finalName>${artifactId}-${jbosscache-core-version}</finalName>
+ <outputDirectory>target/distribution</outputDirectory>
+ <workDirectory>target/assembly/work</workDirectory>
</configuration>
- </execution>
-
- <!-- The Tutorial -->
- <execution>
- <id>tutorial_en</id>
- <phase>package</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ <mainClass>org.jboss.cache.Version</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>build-test-jar</id>
<goals>
- <goal>resources</goal>
- <goal>generate</goal>
+ <goal>test-jar</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:/xslt/org/jboss/pdf.xsl</stylesheetResource>
- <finalName>tutorial_en.pdf</finalName>
- </format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- </formats>
- <options>
- <xincludeSupported>false</xincludeSupported>
- </options>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ </archive>
</configuration>
- </execution>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>2.4.3-JBOSS</version>
+ </plugin>
+ </plugins>
+ </reporting>
- <!-- 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:/xslt/org/jboss/pdf.xsl</stylesheetResource>
- <finalName>faq_en.pdf</finalName>
- </format>
- <format>
- <formatName>html</formatName>
- <stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- <format>
- <formatName>html_single</formatName>
- <stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl</stylesheetResource>
- <finalName>index.html</finalName>
- </format>
- </formats>
- <options>
- <xincludeSupported>false</xincludeSupported>
- </options>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
+ <!-- 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>
+ <repository>
+ <id>snapshots.jboss.org</id>
+ <url>http://snapshots.jboss.org/maven2</url>
+ </repository>
+ <!-- For Amazon S3 artifacts -->
+ <repository>
+ <id>e-xml.sourceforge.net</id>
+ <url>http://e-xml.sourceforge.net/maven2/repository</url>
+ </repository>
+ </repositories>
- <profile>
- <id>test-hudson</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- <properties>
- <defaultTestGroup>functional,unit</defaultTestGroup>
- <protocol.stack>tcp</protocol.stack>
- </properties>
- </profile>
+ <profiles>
+ <profile>
+ <!-- This testMoreState generates Javadocs and the UserGuide, FAQs and Tutorial in the "package" phase. -->
+ <id>Docs</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <properties>
+ <!-- override to generate javadocs in the "package" phase -->
+ <javadocPhase>package</javadocPhase>
+ </properties>
+ <build>
+ <plugins>
+ <!-- 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</groupId>
+ <artifactId>jbossorg-docbook-xslt</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jbossorg-jdocbook-style</artifactId>
+ <version>1.1.0</version>
+ <type>jdocbook-style</type>
+ </dependency>
+ </dependencies>
+ <executions>
- <profile>
- <id>test-functional</id>
- <properties>
- <defaultTestGroup>functional</defaultTestGroup>
- <protocol.stack>tcp</protocol.stack>
- </properties>
- </profile>
+ <!-- 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:/xslt/org/jboss/pdf.xsl</stylesheetResource>
+ <finalName>userguide_en.pdf</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl
+ </stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>false</xincludeSupported>
+ </options>
+ </configuration>
+ </execution>
- <profile>
- <id>test-unit</id>
- <properties>
- <defaultTestGroup>unit</defaultTestGroup>
- </properties>
- </profile>
+ <!-- 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:/xslt/org/jboss/pdf.xsl</stylesheetResource>
+ <finalName>tutorial_en.pdf</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl
+ </stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>false</xincludeSupported>
+ </options>
+ </configuration>
+ </execution>
- <profile>
- <id>test-jgroups</id>
- <properties>
- <defaultTestGroup>jgroups</defaultTestGroup>
- </properties>
- </profile>
+ <!-- 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:/xslt/org/jboss/pdf.xsl</stylesheetResource>
+ <finalName>faq_en.pdf</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath:/xslt/org/jboss/xhtml.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath:/xslt/org/jboss/xhtml-single.xsl
+ </stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>false</xincludeSupported>
+ </options>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
- <profile>
- <id>test-transaction</id>
- <properties>
- <defaultTestGroup>transaction</defaultTestGroup>
- </properties>
- </profile>
+ <profile>
+ <id>test-hudson</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <defaultTestGroup>functional,unit</defaultTestGroup>
+ <protocol.stack>tcp</protocol.stack>
+ </properties>
+ </profile>
- <profile>
- <id>profiling</id>
- <properties>
- <defaultTestGroup>profiling</defaultTestGroup>
- </properties>
- </profile>
+ <profile>
+ <id>test-functional</id>
+ <properties>
+ <defaultTestGroup>functional</defaultTestGroup>
+ <protocol.stack>tcp</protocol.stack>
+ </properties>
+ </profile>
- <profile>
- <id>test-integration</id>
- <properties>
- <defaultTestGroup>integration</defaultTestGroup>
- <protocol.stack>udp</protocol.stack>
- </properties>
- </profile>
+ <profile>
+ <id>test-unit</id>
+ <properties>
+ <defaultTestGroup>unit</defaultTestGroup>
+ </properties>
+ </profile>
+ <profile>
+ <id>test-jgroups</id>
+ <properties>
+ <defaultTestGroup>jgroups</defaultTestGroup>
+ </properties>
+ </profile>
- <profile>
- <id>JBossAS</id>
- <activation>
- <activeByDefault>false</activeByDefault>
- </activation>
- <properties>
- <jbosscache-core-version>3.0.3-SNAPSHOT-JBossAS</jbosscache-core-version>
- <defaultTestGroup>functional,unit</defaultTestGroup>
- <protocol.stack>tcp</protocol.stack>
- </properties>
- <dependencies>
- <dependency>
- <groupId>jgroups</groupId>
- <artifactId>jgroups</artifactId>
- <version>2.6.7.GA</version>
- </dependency>
- <!-- Replaces javax.transaction/jta -->
- <dependency>
- <groupId>org.jboss.javaee</groupId>
- <artifactId>jboss-javaee</artifactId>
- <version>5.0.0.GA</version>
- </dependency>
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-common-core</artifactId>
- <version>2.2.10.GA</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1.0.jboss</version>
- </dependency>
- <dependency>
- <groupId>jboss.jbossts</groupId>
- <artifactId>jbossjta</artifactId>
- <version>4.4.0.GA</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
+ <profile>
+ <id>test-transaction</id>
+ <properties>
+ <defaultTestGroup>transaction</defaultTestGroup>
+ </properties>
+ </profile>
+
+ <profile>
+ <id>profiling</id>
+ <properties>
+ <defaultTestGroup>profiling</defaultTestGroup>
+ </properties>
+ </profile>
+
+ <profile>
+ <id>test-integration</id>
+ <properties>
+ <defaultTestGroup>integration</defaultTestGroup>
+ <protocol.stack>udp</protocol.stack>
+ </properties>
+ </profile>
+
+
+ <profile>
+ <id>JBossAS</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <properties>
+ <jbosscache-core-version>3.0.3-SNAPSHOT-JBossAS</jbosscache-core-version>
+ <defaultTestGroup>functional,unit</defaultTestGroup>
+ <protocol.stack>tcp</protocol.stack>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>jgroups</groupId>
+ <artifactId>jgroups</artifactId>
+ <version>2.6.7.GA</version>
+ </dependency>
+ <!-- Replaces javax.transaction/jta -->
+ <dependency>
+ <groupId>org.jboss.javaee</groupId>
+ <artifactId>jboss-javaee</artifactId>
+ <version>5.0.0.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
+ <version>2.2.10.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1.0.jboss</version>
+ </dependency>
+ <dependency>
+ <groupId>jboss.jbossts</groupId>
+ <artifactId>jbossjta</artifactId>
+ <version>4.4.0.GA</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
</project>
Modified: core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/DataContainerImpl.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -30,9 +30,11 @@
import org.jboss.cache.factories.annotations.NonVolatile;
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.factories.annotations.Stop;
+import org.jboss.cache.jmx.annotations.MBean;
import org.jboss.cache.jmx.annotations.ManagedOperation;
import org.jboss.cache.lock.LockManager;
import org.jboss.cache.marshall.NodeData;
+import org.jboss.cache.util.CachePrinter;
import java.util.ArrayList;
import java.util.Collections;
@@ -48,6 +50,7 @@
* @since 2.2
*/
@NonVolatile
+@MBean(objectName = "DataContainer", description = "Core container for all cached items")
public class DataContainerImpl implements DataContainer
{
private static final Log log = LogFactory.getLog(DataContainerImpl.class);
@@ -193,7 +196,10 @@
public NodeSPI peek(Fqn fqn, boolean includeDeletedNodes, boolean includeInvalidNodes)
{
- if (trace) log.trace("peek " + fqn + ", includeDeletedNodes:" +includeDeletedNodes + ", includeInvalidNodes:" + includeInvalidNodes);
+ if (trace)
+ {
+ log.trace("peek " + fqn + ", includeDeletedNodes:" + includeDeletedNodes + ", includeInvalidNodes:" + includeInvalidNodes);
+ }
if (fqn == null || fqn.size() == 0) return getRoot();
NodeSPI n = getRoot();
int fqnSize = fqn.size();
@@ -483,7 +489,13 @@
return sb.toString();
}
+ @ManagedOperation(description = "Prints details of the data container, formatted as an HTML String")
+ public String printDetailsAsHtml()
+ {
+ return CachePrinter.formatHtml(printDetails());
+ }
+
/**
* Returns lock information.
*
Modified: core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -57,7 +57,6 @@
import org.jgroups.ChannelNotConnectedException;
import org.jgroups.ExtendedMembershipListener;
import org.jgroups.JChannel;
-import org.jgroups.StateTransferException;
import org.jgroups.View;
import org.jgroups.blocks.GroupRequest;
import org.jgroups.blocks.RspFilter;
@@ -83,7 +82,7 @@
*
* @author <a href="mailto:manik AT jboss DOT org">Manik Surtani (manik AT jboss DOT org)</a>
*/
-@MBean(objectName = "RPCManager")
+@MBean(objectName = "RPCManager", description = "Manages RPC connections to remote caches")
public class RPCManagerImpl implements RPCManager
{
private Channel channel;
@@ -176,7 +175,9 @@
isInLocalMode = false;
isUsingBuddyReplication = configuration.getBuddyReplicationConfig() != null && configuration.getBuddyReplicationConfig().isEnabled();
if (log.isDebugEnabled())
+ {
log.debug("Cache mode is " + configuration.getCacheMode());
+ }
boolean fetchState = shouldFetchStateOnStartup();
boolean nonBlocking = configuration.isNonBlockingStateTransfer();
@@ -188,10 +189,14 @@
{
// Allow commands to be ACKed during state transfer
if (nonBlocking)
+ {
componentRegistry.setBlockInStarting(false);
+ }
channel.connect(configuration.getClusterName());
if (log.isInfoEnabled())
+ {
log.info("Cache local address is " + getLocalAddress());
+ }
}
catch (ChannelException e)
{
@@ -199,7 +204,9 @@
}
if (!fetchState)
+ {
return;
+ }
}
@@ -216,10 +223,14 @@
{
channel.connect(configuration.getClusterName(), null, null, configuration.getStateRetrievalTimeout());
if (log.isInfoEnabled())
+ {
log.info("Cache local address is " + getLocalAddress());
+ }
if (members.size() > 1)
+ {
messageListener.waitForState();
+ }
}
catch (ChannelException e)
{
@@ -235,7 +246,9 @@
}
if (log.isDebugEnabled())
+ {
log.debug("state was retrieved successfully (in " + (System.currentTimeMillis() - start) + " milliseconds)");
+ }
}
}
@@ -244,7 +257,9 @@
{
if (members.size() < 2)
+ {
return;
+ }
boolean success = false;
@@ -254,12 +269,16 @@
for (Address member : members)
{
if (member.equals(getLocalAddress()))
+ {
continue;
+ }
try
{
if (log.isTraceEnabled())
+ {
log.trace("Trying to fetch state from: " + member);
+ }
if (getState(null, member))
{
messageListener.waitForState();
@@ -270,14 +289,18 @@
catch (Exception e)
{
if (log.isTraceEnabled())
+ {
log.trace("Error while fetching state", e);
+ }
}
}
if (!success)
{
if (trace)
+ {
log.trace("Could not find available peer for state, backing off and retrying");
+ }
try
{
@@ -360,7 +383,9 @@
ReflectionUtil.setValue(configuration, "accessible", true);
configuration.setUsingMultiplexer(true);
if (log.isDebugEnabled())
+ {
log.debug("Created Multiplexer Channel for cache cluster " + configuration.getClusterName() + " using stack " + configuration.getMultiplexerStack());
+ }
}
else
{
@@ -536,9 +561,13 @@
int modeToUse = mode;
int preferredMode;
if ((preferredMode = spi.getInvocationContext().getOptionOverrides().getGroupRequestMode()) > -1)
+ {
modeToUse = preferredMode;
+ }
if (trace)
+ {
log.trace("callRemoteMethods(): valid members are " + recipients + " methods: " + command + " Using OOB? " + useOutOfBandMessage + " modeToUse: " + modeToUse);
+ }
if (channel.flushSupported() && !flushBlockGate.await(configuration.getStateRetrievalTimeout(), TimeUnit.MILLISECONDS))
{
throw new TimeoutException("State retrieval timed out waiting for flush unblock. (timeout = " + configuration.getStateRetrievalTimeout() + " millis) ");
@@ -547,7 +576,9 @@
RspList rsps = rpcDispatcher.invokeRemoteCommands(recipients, command, modeToUse, timeout, isUsingBuddyReplication, useOutOfBandMessage, responseFilter);
if (mode == GroupRequest.GET_NONE) return Collections.emptyList();// async case
if (trace)
+ {
log.trace("(" + getLocalAddress() + "): responses for method " + command.getClass().getSimpleName() + ":\n" + rsps);
+ }
// short-circuit no-return-value calls.
if (rsps == null) return Collections.emptyList();
List<Object> retval = new ArrayList<Object>(rsps.size());
@@ -618,7 +649,9 @@
// Yes -- cache is configured LOCAL but app doesn't know it -- Brian
//throw new IllegalArgumentException("Cannot fetch partial state, targets are " + sources + " and stateId is " + stateId);
if (log.isWarnEnabled())
+ {
log.warn("Cannot fetch partial state, targets are " + sources + " and stateId is " + stateId);
+ }
return;
}
@@ -636,14 +669,18 @@
}
if (log.isDebugEnabled())
+ {
log.debug("Node " + getLocalAddress() + " fetching partial state " + stateId + " from members " + targets);
+ }
boolean successfulTransfer = false;
for (Address target : targets)
{
try
{
if (log.isDebugEnabled())
+ {
log.debug("Node " + getLocalAddress() + " fetching partial state " + stateId + " from member " + target);
+ }
messageListener.setStateSet(false);
successfulTransfer = getState(stateId, target);
if (successfulTransfer)
@@ -659,14 +696,18 @@
}
}
if (log.isDebugEnabled())
+ {
log.debug("Node " + getLocalAddress() + " fetching partial state " + stateId + " from member " + target + (successfulTransfer ? " successful" : " failed"));
+ }
if (successfulTransfer) break;
}
catch (IllegalStateException ise)
{
// thrown by the JGroups channel if state retrieval fails.
if (log.isInfoEnabled())
+ {
log.info("Channel problems fetching state. Continuing on to next provider. ", ise);
+ }
}
}
@@ -680,18 +721,18 @@
private boolean getState(String stateId, Address target) throws ChannelNotConnectedException, ChannelClosedException
{
lastStateTransferSource = target;
- return ((JChannel)channel).getState(target, stateId, configuration.getStateRetrievalTimeout(), !configuration.isNonBlockingStateTransfer());
+ return ((JChannel) channel).getState(target, stateId, configuration.getStateRetrievalTimeout(), !configuration.isNonBlockingStateTransfer());
}
public void waitForFlush(long timeout)
{
- for (;;)
+ for (; ;)
{
try
{
if (channel.flushSupported() && !flushWaitGate.await(timeout, TimeUnit.MILLISECONDS))
{
- throw new TimeoutException("State retrieval timed out waiting for flush to block. (timeout = " + timeout+ " millis) ");
+ throw new TimeoutException("State retrieval timed out waiting for flush to block. (timeout = " + timeout + " millis) ");
}
return;
}
@@ -706,10 +747,10 @@
// ------------ START: Informational methods ------------
- @ManagedAttribute (description = "Local address")
+ @ManagedAttribute(description = "Local address")
public String getLocalAddressString()
{
- Address address = getLocalAddress();
+ Address address = getLocalAddress();
return address == null ? "null" : address.toString();
}
@@ -723,7 +764,7 @@
return channel != null ? channel.getLocalAddress() : null;
}
- @ManagedAttribute (description = "Cluster view")
+ @ManagedAttribute(description = "Cluster view")
public String getMembersString()
{
List l = getMembers();
@@ -734,9 +775,13 @@
{
if (isInLocalMode) return null;
if (members == null)
+ {
return Collections.emptyList();
+ }
else
+ {
return members;
+ }
}
public boolean isCoordinator()
@@ -834,7 +879,7 @@
catch (Throwable e)
{
//do not rethrow! jgroups might behave funny, resulting even in deadlock
- log.error("Error found while processing view accepted!!!", e);
+ log.error("Error found while processing view accepted!!!", e);
}
}
@@ -933,6 +978,12 @@
return statisticsEnabled;
}
+ @ManagedAttribute(description = "whether or not the RPCManager is used in this cache instance")
+ public boolean isEnabled()
+ {
+ return !isInLocalMode;
+ }
+
@ManagedAttribute
public void setStatisticsEnabled(boolean statisticsEnabled)
{
@@ -958,7 +1009,9 @@
{
//if we use a shared transport do not log any warn message
if (configuration.getMultiplexerStack() != null)
+ {
return;
+ }
//bundling is not good for sync caches
Configuration.CacheMode cacheMode = configuration.getCacheMode();
if (!cacheMode.equals(Configuration.CacheMode.LOCAL) && configuration.getCacheMode().isSynchronous())
Modified: core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -24,7 +24,9 @@
import net.jcip.annotations.ThreadSafe;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import static org.jboss.cache.Region.Type.*;
+import static org.jboss.cache.Region.Type.ANY;
+import static org.jboss.cache.Region.Type.EVICTION;
+import static org.jboss.cache.Region.Type.MARSHALLING;
import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
import org.jboss.cache.buddyreplication.BuddyManager;
import org.jboss.cache.config.Configuration;
@@ -36,6 +38,7 @@
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.factories.annotations.Stop;
+import org.jboss.cache.jmx.annotations.MBean;
import org.jboss.cache.jmx.annotations.ManagedAttribute;
import org.jboss.cache.jmx.annotations.ManagedOperation;
import org.jboss.cache.lock.LockManager;
@@ -55,6 +58,7 @@
* @since 3.0.0
*/
@ThreadSafe
+@MBean(objectName = "RegionManager", description = "Manages eviction and marshalling regions")
public class RegionManagerImpl implements RegionManager
{
/**
@@ -141,7 +145,9 @@
setDefaultInactive(configuration.isInactiveOnStartup());
if (isUsingEvictions())
+ {
evictionTimerTask.init(evictionConfig.getWakeupInterval(), configuration.getRuntimeConfig().getEvictionTimerThreadFactory(), regionsRegistry);
+ }
}
@Stop
@@ -420,7 +426,9 @@
// Don't bother trying to fetch state if we are in LOCAL mode
if (members != null && !members.isEmpty())
+ {
rpcManager.fetchPartialState(members, subtreeRoot.getFqn());
+ }
}
else if (!buddyFqnTransformer.isBackupFqn(fqn))
{
@@ -431,7 +439,9 @@
{
List<Address> sources = new ArrayList<Address>(1);
if (!cache.getMembers().contains(buddy))
+ {
continue;
+ }
sources.add(buddy);
Fqn buddyRoot = buddyFqnTransformer.getBackupFqn(buddy, fqn);
subtreeRoot = cache.peek(buddyRoot, false, false);
@@ -642,7 +652,9 @@
{
if ((type == EVICTION && r.getEvictionRegionConfig() != null) ||
(type == MARSHALLING && r.isActive() && r.getClassLoader() != null))
+ {
regions.add(r);
+ }
}
}
else
@@ -673,7 +685,9 @@
// needDefault = ercs.size() == 0;
if (evictionConfig.getDefaultEvictionRegionConfig().getEvictionAlgorithmConfig() != null &&
!ercs.contains(evictionConfig.getDefaultEvictionRegionConfig())) // then the default is a real region too; not just a template for others
+ {
ercs.add(0, evictionConfig.getDefaultEvictionRegionConfig());
+ }
// create regions for the regions defined in the evictionConfig.
// scan to be sure the _default_ region isn't added twice
@@ -746,7 +760,7 @@
evictionTimerTask.stop();
}
- @ManagedAttribute(name="numRegions", description = "A count of all regions")
+ @ManagedAttribute(name = "numRegions", description = "A count of all regions")
public int getNumRegions()
{
return regionsRegistry.size();
Modified: core/trunk/src/main/java/org/jboss/cache/Version.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Version.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/Version.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -32,10 +32,10 @@
@Immutable
public class Version
{
- public static final String version = "3.0.3-SNAPSHOT";
- public static final String codename = "Naga";
+ public static final String version = "3.1.0-SNAPSHOT";
+ public static final String codename = "Cascabel";
//public static final String cvs = "$Id$";
- static final byte[] version_id = {'0', '3', '0', '3', 'S'};
+ static final byte[] version_id = {'0', '3', '1', '0', 'S'};
private static final int MAJOR_SHIFT = 11;
private static final int MINOR_SHIFT = 6;
@@ -71,9 +71,13 @@
if (v != null)
{
if (len <= 0)
+ {
len = v.length;
+ }
for (int i = 0; i < len; i++)
+ {
sb.append((char) v[i]);
+ }
}
return sb.toString();
}
@@ -92,13 +96,19 @@
public static boolean compareTo(byte[] v)
{
if (v == null)
+ {
return false;
+ }
if (v.length < version_id.length)
+ {
return false;
+ }
for (int i = 0; i < version_id.length; i++)
{
if (version_id[i] != v[i])
+ {
return false;
+ }
}
return true;
}
@@ -116,31 +126,45 @@
public static short getVersionShort(String versionString)
{
if (versionString == null)
+ {
throw new IllegalArgumentException("versionString is null");
+ }
// Special cases for version prior to 1.2.4.SP2
if ("1.2.4".equals(versionString))
+ {
return 124;
+ }
else if ("1.2.4.SP1".equals(versionString))
+ {
return 1241;
+ }
String parts[] = versionString.split("[\\.\\-]");
int a = 0;
int b = 0;
int c = 0;
if (parts.length > 0)
+ {
a = Integer.parseInt(parts[0]);
+ }
if (parts.length > 1)
+ {
b = Integer.parseInt(parts[1]);
+ }
if (parts.length > 2)
+ {
c = Integer.parseInt(parts[2]);
+ }
return encodeVersion(a, b, c);
}
public static String getVersionString(short versionShort)
{
if (versionShort == SHORT_1_2_4_SP2)
+ {
return "1.2.4.SP2";
+ }
switch (versionShort)
{
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -86,17 +86,13 @@
* See {@link org.jboss.cache.interceptors.EvictionInterceptor#visitEvictFqnCommand(org.jboss.cache.InvocationContext , EvictCommand)}
* which is where the return value is used
*
- * @return true if the node was removed from the tree or if it is resident. Returns false if the node still exists; i.e. was only data removed because it still has children.
+ * @return true if the node is now absent from the cache. Returns false if the node still exists; i.e. was only data removed because it still has children.
*/
public Object perform(InvocationContext ctx)
{
NodeSPI node = lookupForEviction(ctx, fqn);
- if (node == null || node.isDeleted())
+ if (node == null || node.isDeleted() || node.isResident())
{
- return false;
- }
- else if (node.isResident())
- {
return true;
}
else if (recursive)
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -152,7 +152,9 @@
{
double total = hits + misses;
if (total == 0)
+ {
return 0;
+ }
return (hits / total);
}
@@ -160,7 +162,9 @@
public double getReadWriteRatio()
{
if (stores == 0)
+ {
return 0;
+ }
return (((double) (hits + misses) / (double) stores));
}
@@ -169,7 +173,9 @@
{
long total = hits + misses;
if (total == 0)
+ {
return 0;
+ }
return (hitTimes + missTimes) / total;
}
@@ -177,17 +183,19 @@
public long getAverageWriteTime()
{
if (stores == 0)
+ {
return 0;
+ }
return (storeTimes) / stores;
}
- @ManagedAttribute(description = "number of cache eviction operations")
+ @ManagedAttribute(description = "number of cache attributes")
public int getNumberOfAttributes()
{
return dataContainer.getNumberOfAttributes();
}
- @ManagedAttribute
+ @ManagedAttribute(description = "number of nodes in the cache")
public int getNumberOfNodes()
{
return dataContainer.getNumberOfNodes();
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -81,8 +81,8 @@
// See if the node still exists; i.e. was only data removed
// because it still has children.
// If yes, put an ADD event in the queue so the node gets revisited
- boolean complete = (retVal != null && (Boolean) retVal);
- if (!complete)
+ boolean nodeIsNowAbsent = (retVal != null && (Boolean) retVal);
+ if (!nodeIsNowAbsent)
{
Region r;
if (fqn != null && (r = getRegion(fqn)) != null)
@@ -244,10 +244,10 @@
private void registerEvictionEventToRegionManager(Fqn fqn, EvictionEvent.Type type, int elementDifference, Region region)
{
//we do not trigger eviction events for resident nodes
- if (dataContainer.isResident(fqn))
+ if (dataContainer.isResident(fqn))
{
- if (trace) log.trace("Ignoring Fqn " + fqn + " as it is marked as resident");
- return;
+ if (trace) log.trace("Ignoring Fqn " + fqn + " as it is marked as resident");
+ return;
}
region.registerEvictionEvent(fqn, type, elementDifference);
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -30,6 +30,8 @@
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.interceptors.base.CommandInterceptor;
import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.jmx.annotations.MBean;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
import org.jboss.cache.util.CachePrinter;
import java.util.ArrayList;
@@ -45,6 +47,7 @@
* todo - if you add the same interceptor instance twice, things get really dirty.
* -- this should be treated as an missuse and an exception should be thrown
*/
+@MBean(description = "InterceptorChain")
public class InterceptorChain
{
/**
@@ -151,6 +154,25 @@
}
+ @ManagedOperation(description = "Retrieves a list of the interceptors in the chain")
+ public String getInterceptorDetails()
+ {
+ StringBuilder sb = new StringBuilder("Interceptor chain: \n");
+ int count = 0;
+ for (CommandInterceptor i : asList())
+ {
+ count++;
+ sb.append(" ").append(count).append(". ").append(i).append("\n");
+ }
+ return sb.toString();
+ }
+
+ @ManagedOperation(description = "Retrieves a list of the interceptors in the chain, formatted as HTML")
+ public String getInterceptorDetailsAsHtml()
+ {
+ return CachePrinter.formatHtml(getInterceptorDetails());
+ }
+
/**
* Returns an unmofiable list with all the interceptors in sequence.
* If first in chain is null an empty list is returned.
Modified: core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -48,16 +48,7 @@
import org.jgroups.jmx.JChannelFactoryMBean;
import org.w3c.dom.Element;
-import javax.management.AttributeChangeNotification;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
+import javax.management.*;
import javax.transaction.TransactionManager;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -146,7 +137,7 @@
public String printConfigurationAsHtmlString()
{
Configuration cfg = getConfiguration();
- return cfg == null ? "Configuration is null" : formatHtml(cfg.toString());
+ return cfg == null ? "Configuration is null" : CachePrinter.formatHtml(cfg.toString());
}
public String printCacheDetails()
@@ -156,7 +147,7 @@
public String printCacheDetailsAsHtml()
{
- return cache == null ? "Cache is null" : formatHtml(CachePrinter.printCacheDetails(cache));
+ return cache == null ? "Cache is null" : CachePrinter.formatHtml(CachePrinter.printCacheDetails(cache));
}
public CacheStatus getCacheStatus()
@@ -217,7 +208,7 @@
public String printLockInfoAsHtml()
{
- return cache == null ? "Cache is null" : formatHtml(CachePrinter.printCacheLockingInfo(cache));
+ return cache == null ? "Cache is null" : CachePrinter.formatHtml(CachePrinter.printCacheLockingInfo(cache));
}
public boolean getRegisterJmxResource()
@@ -599,9 +590,13 @@
if (!cacheStatus.createAllowed())
{
if (cacheStatus.needToDestroyFailedCache())
+ {
destroy();
+ }
else
+ {
return;
+ }
}
try
@@ -633,12 +628,18 @@
if (!cacheStatus.startAllowed())
{
if (cacheStatus.needToDestroyFailedCache())
+ {
destroy(); // this will take us back to DESTROYED
+ }
if (cacheStatus.needCreateBeforeStart())
+ {
create();
+ }
else
+ {
return;
+ }
}
try
@@ -718,7 +719,9 @@
}
}
else
+ {
return;
+ }
}
try
@@ -730,7 +733,9 @@
unregisterJmxResources();
if (cache != null)
+ {
cache.destroy();
+ }
}
finally
{
@@ -901,22 +906,6 @@
return server;
}
- /**
- * Formats a given String for display as an HTML snippet.
- *
- * @param s string to format
- * @return formatted string
- */
- public static String formatHtml(String s)
- {
- s = s.replaceAll("\r\n", "<br/>");
- s = s.replaceAll("\r", "<br/>");
- s = s.replaceAll("\n", "<br/>");
- s = s.replaceAll("\t", " ");
- s = s.replaceAll(" ", " ");
- return s;
- }
-
public String getNotificationServiceName()
{
return notificationServiceName;
@@ -1049,14 +1038,18 @@
{
listenerCount.incrementAndGet();
if (cache != null)
+ {
cache.addCacheListener(cacheNotificationListener);
+ }
}
else
{
if (listenerCount.decrementAndGet() <= 0)
{
if (cache != null)
+ {
cache.removeCacheListener(cacheNotificationListener);
+ }
listenerCount.set(0);
}
@@ -1082,13 +1075,21 @@
sendStateChangeNotification(oldState, getState(), getClass().getSimpleName() + " failed", t);
if (t instanceof CacheException)
+ {
throw (CacheException) t;
+ }
else if (t instanceof RuntimeException)
+ {
throw (RuntimeException) t;
+ }
else if (t instanceof Error)
+ {
throw (Error) t;
+ }
else
+ {
throw new CacheException(t);
+ }
}
/**
@@ -1097,7 +1098,9 @@
private void sendStateChangeNotification(int oldState, int newState, String msg, Throwable t)
{
if (isDisableStateChangeNotifications())
+ {
return;
+ }
long now = System.currentTimeMillis();
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -56,6 +56,7 @@
private static final int VERSION_210 = 21;
private static final int VERSION_220 = 22;
private static final int VERSION_300 = 30;
+ private static final int VERSION_310 = 31;
private static final int CUSTOM_MARSHALLER = 999;
private ComponentRegistry componentRegistry;
@@ -83,7 +84,9 @@
if (marshallerClass != null)
{
if (trace)
+ {
log.trace("Cache marshaller implementation specified as " + marshallerClass + ". Overriding any version strings passed in. ");
+ }
try
{
defaultMarshaller = (Marshaller) Util.loadClass(marshallerClass).newInstance();
@@ -308,11 +311,14 @@
marshallers.put(VERSION_210, marshaller);
}
break;
+ case VERSION_310:
case VERSION_300:
knownVersion = true;
default:
if (!knownVersion && log.isWarnEnabled())
+ {
log.warn("Unknown replication version [" + versionId + "]. Falling back to the default marshaller installed.");
+ }
marshaller = marshallers.get(VERSION_300);
if (marshaller == null)
{
Modified: core/trunk/src/main/java/org/jboss/cache/util/CachePrinter.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/CachePrinter.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/main/java/org/jboss/cache/util/CachePrinter.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -93,4 +93,20 @@
}
return sb.toString();
}
+
+ /**
+ * Formats a given String for display as an HTML snippet.
+ *
+ * @param s string to format
+ * @return formatted string
+ */
+ public static String formatHtml(String s)
+ {
+ s = s.replaceAll("\r\n", "<br/>");
+ s = s.replaceAll("\r", "<br/>");
+ s = s.replaceAll("\n", "<br/>");
+ s = s.replaceAll("\t", " ");
+ s = s.replaceAll(" ", " ");
+ return s;
+ }
}
Modified: core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -47,6 +47,14 @@
control.verify();
}
+ public void testShouldReturnTrueIndicatingNodeIsAbsentIfNodeDoesntExist()
+ {
+ expect(container.peek(testFqn, false, true)).andReturn(null);
+ control.replay();
+ assert Boolean.TRUE == command.perform(ctx);
+ control.verify();
+ }
+
public void testSimpleEviction()
{
expect(container.peek(testFqn, false, true)).andReturn(nodes.abNode);
Modified: core/trunk/src/test/java/org/jboss/cache/config/parsing/SampleConfigFilesCorrectnessTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/config/parsing/SampleConfigFilesCorrectnessTest.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/test/java/org/jboss/cache/config/parsing/SampleConfigFilesCorrectnessTest.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -21,14 +21,11 @@
*/
package org.jboss.cache.config.parsing;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.jboss.cache.Cache;
-import org.jboss.cache.UnitTestCacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
@@ -54,7 +51,6 @@
private InMemoryAppender appender;
private Level oldLevel;
- private Log log = LogFactory.getLog(SampleConfigFilesCorrectnessTest.class);
@BeforeMethod
public void setUpTest()
Copied: core/trunk/src/test/java/org/jboss/cache/jmx/JmxManualTest.java (from rev 7636, core/trunk/src/test/java/org/jboss/cache/jmx/JmxManualTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/jmx/JmxManualTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/jmx/JmxManualTest.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -0,0 +1,76 @@
+package org.jboss.cache.jmx;
+
+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.config.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.jboss.cache.eviction.FIFOAlgorithmConfig;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+// do NOT enable this test in SVN as it will cause Hudson (or any other continuous integration test harness) to get
+
+// stuck.
+@Test(groups = "maual", enabled = false)
+public class JmxManualTest
+{
+ public void testLocal() throws IOException
+ {
+ Configuration c = new Configuration();
+ Cache cache = new DefaultCacheFactory().createCache(c);
+ cache.put("/a/b/c", "a", "b");
+ cache.put("/a/b/c", "c", "d");
+ cache.put("/a/b/d", "a", "b");
+ cache.put("/a/b/e", "c", "d");
+
+ System.in.read();
+ }
+
+ public void testLocalNoJMX() throws IOException
+ {
+ Configuration c = new Configuration();
+ c.setExposeManagementStatistics(false);
+ Cache cache = new DefaultCacheFactory().createCache(c);
+ cache.put("/a/b/c", "a", "b");
+ cache.put("/a/b/c", "c", "d");
+ cache.put("/a/b/d", "a", "b");
+ cache.put("/a/b/e", "c", "d");
+
+ System.in.read();
+ }
+
+ public void testLocalWithEviction() throws IOException
+ {
+ Configuration c = new Configuration();
+ EvictionConfig ec = new EvictionConfig();
+ ec.setWakeupInterval(250, TimeUnit.MILLISECONDS);
+ EvictionRegionConfig erc = new EvictionRegionConfig();
+ erc.setEvictionAlgorithmConfig(new FIFOAlgorithmConfig(2));
+ erc.setRegionFqn(Fqn.ROOT);
+ ec.setDefaultEvictionRegionConfig(erc);
+ c.setEvictionConfig(ec);
+ Cache cache = new DefaultCacheFactory().createCache(c);
+ cache.put("/a/b/c", "a", "b");
+ cache.put("/a/b/c", "c", "d");
+ cache.put("/a/b/d", "a", "b");
+ cache.put("/a/b/e", "c", "d");
+
+ System.in.read();
+ }
+
+ public void testLocalWithEvictionXML() throws IOException
+ {
+ Cache cache = new DefaultCacheFactory().createCache("config-samples/eviction-enabled.xml");
+ cache.put("/a/b/c", "a", "b");
+ cache.put("/a/b/c", "c", "d");
+ cache.put("/a/b/d", "a", "b");
+ cache.put("/a/b/e", "c", "d");
+
+ System.in.read();
+ }
+
+}
Modified: core/trunk/src/test/java/org/jboss/cache/jmx/deprecated/CacheJmxWrapperTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/jmx/deprecated/CacheJmxWrapperTest.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/test/java/org/jboss/cache/jmx/deprecated/CacheJmxWrapperTest.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -16,7 +16,6 @@
import org.jboss.cache.notifications.event.Event;
import org.jboss.cache.transaction.DummyTransactionManagerLookup;
import org.jboss.cache.util.CachePrinter;
-import org.jboss.cache.util.TestingUtil;
import org.jgroups.Address;
import org.jgroups.stack.IpAddress;
import static org.testng.AssertJUnit.*;
@@ -71,7 +70,9 @@
finally
{
if (registered)
+ {
mBeanServer.unregisterMBean(on);
+ }
}
}
@@ -155,7 +156,7 @@
{
CacheJmxWrapperMBean<String, String> wrapper = registerWrapper();
String cfgFromJmx = wrapper.printConfigurationAsHtmlString();
- assertEquals(CacheJmxWrapper.formatHtml(cache.getConfiguration().toString()), cfgFromJmx);
+ assertEquals(CachePrinter.formatHtml(cache.getConfiguration().toString()), cfgFromJmx);
checkHtml(cfgFromJmx, false);
}
@@ -175,7 +176,7 @@
wrapper.create();
wrapper.start();
String cfgFromJmx = wrapper.printConfigurationAsHtmlString();
- assertEquals(CacheJmxWrapper.formatHtml(wrapper.getCache().getConfiguration().toString()), cfgFromJmx);
+ assertEquals(CachePrinter.formatHtml(wrapper.getCache().getConfiguration().toString()), cfgFromJmx);
checkHtml(cfgFromJmx, false);
}
@@ -396,7 +397,9 @@
private void checkHtml(String html, boolean checkBR)
{
if (checkBR)
+ {
assertTrue("Has <br", html.contains("<br"));
+ }
assertTrue("No tabs", html.indexOf('\t') == -1);
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java 2009-02-05 01:58:42 UTC (rev 7653)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java 2009-02-05 13:00:20 UTC (rev 7654)
@@ -78,7 +78,7 @@
byte[] bytes = marshaller.objectToByteBuffer("Hello");
ObjectInputStream in = new MarshalledValueInputStream(new ByteArrayInputStream(bytes));
- assertEquals("Version header short should be '30'", 30, in.readShort());
+ assertEquals("Version header short should be '30'", 31, in.readShort());
}
public void testVersionHeader210() throws Exception
15 years, 10 months
JBoss Cache SVN: r7653 - core/trunk/src/test/resources.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2009-02-04 20:58:42 -0500 (Wed, 04 Feb 2009)
New Revision: 7653
Modified:
core/trunk/src/test/resources/log4j.xml
Log:
Drop log level to warning
Modified: core/trunk/src/test/resources/log4j.xml
===================================================================
--- core/trunk/src/test/resources/log4j.xml 2009-02-05 01:57:10 UTC (rev 7652)
+++ core/trunk/src/test/resources/log4j.xml 2009-02-05 01:58:42 UTC (rev 7653)
@@ -57,7 +57,7 @@
<!-- ================ -->
<category name="org.jboss.cache">
- <priority value="TRACE"/>
+ <priority value="WARN"/>
</category>
<!-- these two are in separate sections since they
15 years, 10 months
JBoss Cache SVN: r7652 - core/trunk/src/test/java/org/jboss/cache/statetransfer.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2009-02-04 20:57:10 -0500 (Wed, 04 Feb 2009)
New Revision: 7652
Modified:
core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java
Log:
Add comment
Modified: core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java 2009-02-05 00:23:09 UTC (rev 7651)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java 2009-02-05 01:57:10 UTC (rev 7652)
@@ -62,6 +62,9 @@
try
{
+ // This sleep is not required for the test to function,
+ // however it improves the possibility of finding errors
+ // (since it keeps the tx log going)
Thread.sleep(2000);
}
catch (InterruptedException e)
15 years, 10 months
JBoss Cache SVN: r7651 - core/trunk/src/test/java/org/jboss/cache/statetransfer.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2009-02-04 19:23:09 -0500 (Wed, 04 Feb 2009)
New Revision: 7651
Modified:
core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java
Log:
fixed unit test
Modified: core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java 2009-02-05 00:00:18 UTC (rev 7650)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java 2009-02-05 00:23:09 UTC (rev 7651)
@@ -470,8 +470,7 @@
RegionImpl region = (RegionImpl) cache2.getRegion(Fqn.ROOT, false);
// We expect a VISIT event for / and ADD events for /a, /a/b and /a/b/c
int nodeEventQueueSize = region.getEvictionEventQueue().size();
- boolean mvcc = cache2.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.MVCC;
- assertEquals("Saw the expected number of node events", mvcc ? 6 : 4, nodeEventQueueSize);
+ assertTrue("Saw the expected number of node events", nodeEventQueueSize > 5); //one event happens on read root
}
/**
15 years, 10 months
JBoss Cache SVN: r7650 - core/trunk/src/main/java/org/jboss/cache/statetransfer.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2009-02-04 19:00:18 -0500 (Wed, 04 Feb 2009)
New Revision: 7650
Modified:
core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java
Log:
Improve non progress alg
Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java 2009-02-04 23:54:51 UTC (rev 7649)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java 2009-02-05 00:00:18 UTC (rev 7650)
@@ -159,7 +159,7 @@
if (nonBlocking && generateTransient)
{
- for (int nonProgress = 0, size = txLog.size(); nonProgress < maxNonProgressingLogWrites && size > 0;)
+ for (int nonProgress = 0, size = txLog.size(); size > 0;)
{
if (log.isTraceEnabled())
log.trace("Tx Log remaining entries = " + size);
@@ -168,8 +168,8 @@
// If size did not decrease then we did not make progress, and could be wasting
// our time. Limit this to the specified max.
- if (newSize >= size)
- nonProgress++;
+ if (newSize >= size && ++nonProgress >= maxNonProgressingLogWrites)
+ break;
size = newSize;
}
15 years, 10 months
JBoss Cache SVN: r7649 - in core/trunk/src: main/java/org/jboss/cache/config and 8 other directories.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2009-02-04 18:54:51 -0500 (Wed, 04 Feb 2009)
New Revision: 7649
Added:
core/trunk/src/main/java/org/jboss/cache/factories/TransactionLogFactory.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionLog.java
core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java
Modified:
core/trunk/src/main/java/org/jboss/cache/RPCManager.java
core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/config/Configuration.java
core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
core/trunk/src/main/java/org/jboss/cache/marshall/CommandAwareRpcDispatcher.java
core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java
core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java
core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java
core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferManager.java
core/trunk/src/test/java/org/jboss/cache/transaction/PrepareCommitContentionTest.java
core/trunk/src/test/resources/log4j.xml
Log:
Implement NBST
Modified: core/trunk/src/main/java/org/jboss/cache/RPCManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RPCManager.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/RPCManager.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -22,12 +22,14 @@
package org.jboss.cache;
import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.lock.TimeoutException;
import org.jgroups.Address;
import org.jgroups.Channel;
import org.jgroups.blocks.RspFilter;
import java.util.List;
import java.util.Vector;
+import java.util.concurrent.TimeUnit;
/**
* Provides a mechanism for communicating with other caches in the cluster. For now this is based on JGroups as an underlying
@@ -150,4 +152,8 @@
* @return a channel
*/
Channel getChannel();
+
+ public void waitForFlush(long timeout);
+
+ public Address getLastStateTransferSource();
}
Modified: core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/RPCManagerImpl.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -51,8 +51,10 @@
import org.jboss.cache.util.reflect.ReflectionUtil;
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.JChannel;
import org.jgroups.StateTransferException;
@@ -100,7 +102,18 @@
* Thread gate used to block Dispatcher during JGroups FLUSH protocol
*/
private final ReclosableLatch flushBlockGate = new ReclosableLatch();
+
/**
+ * Thread gate used by NBST to wait for a flush
+ */
+ private final ReclosableLatch flushWaitGate = new ReclosableLatch(false);
+
+ /**
+ * The most recent state transfer source
+ */
+ volatile Address lastStateTransferSource;
+
+ /**
* JGroups RpcDispatcher in use.
*/
private CommandAwareRpcDispatcher rpcDispatcher = null;
@@ -109,7 +122,7 @@
* JGroups message listener.
*/
private ChannelMessageListener messageListener;
- private Configuration configuration;
+ Configuration configuration;
private Notifier notifier;
private CacheSPI spi;
private InvocationContextContainer invocationContextContainer;
@@ -148,6 +161,7 @@
@Start(priority = 15)
public void start()
{
+
switch (configuration.getCacheMode())
{
case LOCAL:
@@ -161,56 +175,131 @@
case INVALIDATION_SYNC:
isInLocalMode = false;
isUsingBuddyReplication = configuration.getBuddyReplicationConfig() != null && configuration.getBuddyReplicationConfig().isEnabled();
- if (log.isDebugEnabled()) log.debug("Cache mode is " + configuration.getCacheMode());
+ if (log.isDebugEnabled())
+ log.debug("Cache mode is " + configuration.getCacheMode());
boolean fetchState = shouldFetchStateOnStartup();
- initialiseChannelAndRpcDispatcher(fetchState);
+ boolean nonBlocking = configuration.isNonBlockingStateTransfer();
+ initialiseChannelAndRpcDispatcher(fetchState && !nonBlocking);
- if (fetchState)
+ if (!fetchState || nonBlocking)
{
try
{
- long start = System.currentTimeMillis();
- // connect and state transfer
- channel.connect(configuration.getClusterName(), null, null, configuration.getStateRetrievalTimeout());
- //if I am not the only and the first member than wait for a state to arrive
- if (getMembers().size() > 1) messageListener.waitForState();
-
- if (log.isDebugEnabled())
- log.debug("connected, state was retrieved successfully (in " + (System.currentTimeMillis() - start) + " milliseconds)");
+ // Allow commands to be ACKed during state transfer
+ if (nonBlocking)
+ componentRegistry.setBlockInStarting(false);
+ channel.connect(configuration.getClusterName());
+ if (log.isInfoEnabled())
+ log.info("Cache local address is " + getLocalAddress());
}
- catch (StateTransferException ste)
- {
- // make sure we disconnect from the channel before we throw this exception!
- // JBCACHE-761
- disconnect();
- throw new CacheException("Unable to fetch state on startup", ste);
- }
catch (ChannelException e)
{
throw new CacheException("Unable to connect to JGroups channel", e);
}
- catch (Exception ex)
- {
- throw new CacheException("Unable to fetch state on startup", ex);
- }
+
+ if (!fetchState)
+ return;
}
+
+
+ List<Address> members = getMembers();
+
+ long start = System.currentTimeMillis();
+ if (nonBlocking)
+ {
+ startNonBlockStateTransfer(members);
+ }
else
{
- //otherwise just connect
try
{
- channel.connect(configuration.getClusterName());
+ channel.connect(configuration.getClusterName(), null, null, configuration.getStateRetrievalTimeout());
+ if (log.isInfoEnabled())
+ log.info("Cache local address is " + getLocalAddress());
+
+ if (members.size() > 1)
+ messageListener.waitForState();
}
catch (ChannelException e)
{
throw new CacheException("Unable to connect to JGroups channel", e);
}
+ catch (Exception ex)
+ {
+ // make sure we disconnect from the channel before we throw this exception!
+ // JBCACHE-761
+ disconnect();
+ throw new CacheException("Unable to fetch state on startup", ex);
+ }
}
- if (log.isInfoEnabled()) log.info("Cache local address is " + getLocalAddress());
+
+ if (log.isDebugEnabled())
+ log.debug("state was retrieved successfully (in " + (System.currentTimeMillis() - start) + " milliseconds)");
}
+
}
+ private void startNonBlockStateTransfer(List<Address> members)
+ {
+
+ if (members.size() < 2)
+ return;
+
+ boolean success = false;
+
+ outer:
+ for (int i = 0, wait = 1000; i < 5; i++)
+ {
+ for (Address member : members)
+ {
+ if (member.equals(getLocalAddress()))
+ continue;
+
+ try
+ {
+ if (log.isTraceEnabled())
+ log.trace("Trying to fetch state from: " + member);
+ if (getState(null, member))
+ {
+ messageListener.waitForState();
+ success = true;
+ break outer;
+ }
+ }
+ catch (Exception e)
+ {
+ if (log.isTraceEnabled())
+ log.trace("Error while fetching state", e);
+ }
+ }
+
+ if (!success)
+ {
+ if (trace)
+ log.trace("Could not find available peer for state, backing off and retrying");
+
+ try
+ {
+ Thread.sleep(wait <<= 2);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ }
+
+ if (!success)
+ {
+ disconnect();
+ throw new CacheException("Unable to fetch state on startup");
+ }
+
+ componentRegistry.setBlockInStarting(true);
+ }
+
public void disconnect()
{
if (channel != null && channel.isOpen())
@@ -316,12 +405,12 @@
if (configuration.isUseRegionBasedMarshalling())
{
rpcDispatcher = new InactiveRegionAwareRpcDispatcher(channel, messageListener, new MembershipListenerAdaptor(),
- spi, invocationContextContainer, interceptorChain, componentRegistry);
+ spi, invocationContextContainer, interceptorChain, componentRegistry, flushBlockGate);
}
else
{
rpcDispatcher = new CommandAwareRpcDispatcher(channel, messageListener, new MembershipListenerAdaptor(),
- invocationContextContainer, invocationContextContainer, interceptorChain, componentRegistry);
+ invocationContextContainer, invocationContextContainer, interceptorChain, componentRegistry, flushBlockGate);
}
checkAppropriateConfig();
rpcDispatcher.setRequestMarshaller(marshaller);
@@ -556,7 +645,7 @@
if (log.isDebugEnabled())
log.debug("Node " + getLocalAddress() + " fetching partial state " + stateId + " from member " + target);
messageListener.setStateSet(false);
- successfulTransfer = channel.getState(target, stateId, configuration.getStateRetrievalTimeout());
+ successfulTransfer = getState(stateId, target);
if (successfulTransfer)
{
try
@@ -588,6 +677,31 @@
}
+ private boolean getState(String stateId, Address target) throws ChannelNotConnectedException, ChannelClosedException
+ {
+ lastStateTransferSource = target;
+ return ((JChannel)channel).getState(target, stateId, configuration.getStateRetrievalTimeout(), !configuration.isNonBlockingStateTransfer());
+ }
+
+ public void waitForFlush(long timeout)
+ {
+ for (;;)
+ {
+ try
+ {
+ if (channel.flushSupported() && !flushWaitGate.await(timeout, TimeUnit.MILLISECONDS))
+ {
+ throw new TimeoutException("State retrieval timed out waiting for flush to block. (timeout = " + timeout+ " millis) ");
+ }
+ return;
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
// ------------ END: Partial state transfer methods ------------
// ------------ START: Informational methods ------------
@@ -599,6 +713,11 @@
return address == null ? "null" : address.toString();
}
+ public Address getLastStateTransferSource()
+ {
+ return lastStateTransferSource;
+ }
+
public Address getLocalAddress()
{
return channel != null ? channel.getLocalAddress() : null;
@@ -734,6 +853,7 @@
try
{
flushBlockGate.close();
+ flushWaitGate.open();
if (log.isDebugEnabled()) log.debug("Block received at " + getLocalAddress());
notifier.notifyCacheBlocked(true);
notifier.notifyCacheBlocked(false);
@@ -754,6 +874,7 @@
{
try
{
+ flushWaitGate.close();
if (log.isDebugEnabled()) log.debug("UnBlock received at " + getLocalAddress());
notifier.notifyCacheUnblocked(true);
@@ -862,4 +983,4 @@
}
}
}
-}
\ No newline at end of file
+}
Modified: core/trunk/src/main/java/org/jboss/cache/config/Configuration.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/Configuration.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/config/Configuration.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -187,6 +187,7 @@
private boolean exposeManagementStatistics = true;
@Dynamic
private boolean fetchInMemoryState = true;
+ private boolean nonBlockingStateTransfer = false;
private short replicationVersion = DEFAULT_REPLICATION_VERSION;
@Dynamic
private long lockAcquisitionTimeout = 10000;
@@ -474,7 +475,7 @@
/**
* Sets the queue size of the bounded queue used to store async serialization events on. This defaults to 50,000.
- *
+ *
* @param serializationExecutorQueueSize queue size to use
*/
public void setSerializationExecutorQueueSize(int serializationExecutorQueueSize)
@@ -1141,4 +1142,14 @@
return null;
}
+ public boolean isNonBlockingStateTransfer()
+ {
+ return nonBlockingStateTransfer;
+ }
+
+ public void setNonBlockingStateTransfer(boolean nonBlockingStateTransfer)
+ {
+ this.nonBlockingStateTransfer = nonBlockingStateTransfer;
+ }
+
}
Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -105,6 +105,8 @@
*/
private boolean invokedFromShutdownHook;
+ private volatile boolean blockInStarting = true;
+
/**
* Creates an instance of the component registry. The configuration passed in is automatically registered.
*
@@ -202,6 +204,7 @@
s.add(RegionManagerFactory.class);
s.add(NodeMetaFactory.class);
s.add(CommandsMetaFactory.class);
+ s.add(TransactionLogFactory.class);
return s;
}
@@ -883,7 +886,7 @@
log.trace("Is remotely originating.");
// else if this is a remote call and the status is STARTING, wait until the cache starts.
- if (state == CacheStatus.STARTING)
+ if (state == CacheStatus.STARTING && blockInStarting)
{
log.trace("Cache is starting; block.");
try
@@ -1023,4 +1026,9 @@
HashSet<Component> defensiveCopy = new HashSet<Component>(componentLookup.values());
return Collections.unmodifiableSet(defensiveCopy);
}
+
+ public void setBlockInStarting(boolean blockInStarting)
+ {
+ this.blockInStarting = blockInStarting;
+ }
}
Added: core/trunk/src/main/java/org/jboss/cache/factories/TransactionLogFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/TransactionLogFactory.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/TransactionLogFactory.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, 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 org.jboss.cache.factories.annotations.DefaultFactoryFor;
+import org.jboss.cache.transaction.TransactionLog;
+
+/**
+ * Constructs {@link org.jboss.cache.transaction.TransactionLog} instances.
+ *
+ * @author Jason T. Greene
+ * @since 3.0
+ */
+@DefaultFactoryFor(classes = TransactionLog.class)
+public class TransactionLogFactory extends ComponentFactory
+{
+ protected <T> T construct(Class<T> componentType)
+ {
+ return componentType.cast(new TransactionLog());
+ }
+}
Property changes on: core/trunk/src/main/java/org/jboss/cache/factories/TransactionLogFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -21,6 +21,20 @@
*/
package org.jboss.cache.interceptors;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
import org.jboss.cache.CacheException;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.RPCManager;
@@ -51,21 +65,11 @@
import org.jboss.cache.notifications.Notifier;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionContext;
+import org.jboss.cache.transaction.TransactionLog;
import org.jboss.cache.transaction.TransactionTable;
+import org.jboss.cache.util.Immutables;
import org.jboss.cache.util.concurrent.ConcurrentHashSet;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* This interceptor is the new default at the head of all interceptor chains,
* and makes transactional attributes available to all interceptors in the chain.
@@ -83,12 +87,14 @@
private InvocationContextContainer invocationContextContainer;
private ComponentRegistry componentRegistry;
private ContextFactory contextFactory;
+ private TransactionLog transactionLog;
/**
* List <Transaction>that we have registered for
*/
private final Set<Transaction> transactions = new ConcurrentHashSet<Transaction>();
private final Map<Transaction, GlobalTransaction> rollbackTransactions = new ConcurrentHashMap<Transaction, GlobalTransaction>(16);
+
private long prepares = 0;
private long commits = 0;
private long rollbacks = 0;
@@ -99,9 +105,11 @@
@Inject
public void intialize(RPCManager rpcManager, ContextFactory contextFactory,
Notifier notifier, InvocationContextContainer icc,
- CommandsFactory factory, ComponentRegistry componentRegistry, LockManager lockManager)
+ TransactionLog transactionLog, CommandsFactory factory,
+ ComponentRegistry componentRegistry, LockManager lockManager)
{
this.contextFactory = contextFactory;
+ this.transactionLog = transactionLog;
this.commandsFactory = factory;
this.rpcManager = rpcManager;
this.notifier = notifier;
@@ -117,10 +125,12 @@
Object result = null;
// this is a prepare, commit, or rollback.
- if (trace) log.trace("Got gtx from invocation context " + ctx.getGlobalTransaction());
+ GlobalTransaction gtx = ctx.getGlobalTransaction();
+ if (trace) log.trace("Got gtx from invocation context " + gtx);
+
try
{
- if (ctx.getGlobalTransaction().isRemote())
+ if (gtx.isRemote())
{
result = handleRemotePrepare(ctx, command);
if (getStatisticsEnabled()) prepares++;
@@ -142,6 +152,8 @@
@Override
public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable
{
+ GlobalTransaction gtx = ctx.getGlobalTransaction();
+
if (!ctx.getGlobalTransaction().isRemote())
{
if (trace) log.trace("received my own message (discarding it)");
@@ -150,7 +162,7 @@
try
{
if (trace) log.trace("(" + rpcManager.getLocalAddress() + ") call on command [" + command + "]");
- GlobalTransaction gtx = ctx.getGlobalTransaction();
+
Transaction ltx = txTable.getLocalTransaction(gtx, true);
// disconnect if we have a current tx associated
Transaction currentTx = txManager.getTransaction();
@@ -194,7 +206,9 @@
@Override
public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable
{
- if (!ctx.getGlobalTransaction().isRemote())
+ GlobalTransaction gtx = ctx.getGlobalTransaction();
+
+ if (!gtx.isRemote())
{
if (trace) log.trace("received my own message (discarding it)");
return null;
@@ -202,7 +216,6 @@
try
{
if (trace) log.trace("(" + rpcManager.getLocalAddress() + ") call on command [" + command + "]");
- GlobalTransaction gtx = ctx.getGlobalTransaction();
Transaction ltx = txTable.getLocalTransaction(gtx);
if (ltx == null)
{
@@ -268,7 +281,12 @@
{
try
{
- return attachGtxAndPassUpChain(ctx, command);
+ Object ret = attachGtxAndPassUpChain(ctx, command);
+
+ if (command instanceof WriteCommand && ctx.getTransaction() == null)
+ transactionLog.logNoTxWrite((WriteCommand)command);
+
+ return ret;
}
catch (Throwable throwable)
{
@@ -382,6 +400,8 @@
}
else
{
+ transactionLog.logPrepare(command);
+
// now pass up the prepare method itself.
invokeNextInterceptor(ctx, command);
}
@@ -544,11 +564,22 @@
{
try
{
- VisitableCommand commitCommand = onePhaseCommit ? buildPrepareCommand(gtx, modifications, true) : commandsFactory.buildCommitCommand(gtx);
-
if (trace) log.trace("Running commit for " + gtx);
+ VisitableCommand commitCommand = onePhaseCommit ? buildPrepareCommand(gtx, modifications, true)
+ : commandsFactory.buildCommitCommand(gtx);
+
+
handleCommitRollback(ctx, commitCommand);
+
+ if (onePhaseCommit)
+ {
+ transactionLog.logOnePhaseCommit(gtx, modifications);
+ }
+ else
+ {
+ transactionLog.logCommit(gtx);
+ }
}
catch (Throwable e)
{
@@ -595,6 +626,8 @@
VisitableCommand rollbackCommand = commandsFactory.buildRollbackCommand(gtx);
if (trace) log.trace(" running rollback for " + gtx);
+ transactionLog.rollback(gtx);
+
//JBCACHE-359 Store a lookup for the globalTransaction so a listener
// callback can find it
rollbackTransactions.put(tx, gtx);
@@ -630,8 +663,10 @@
public Object runPreparePhase(InvocationContext ctx, GlobalTransaction gtx, List<WriteCommand> modifications) throws Throwable
{
// running a 2-phase commit.
- VisitableCommand prepareCommand = buildPrepareCommand(gtx, modifications, false);
+ PrepareCommand prepareCommand = buildPrepareCommand(gtx, modifications, false);
+ transactionLog.logPrepare(prepareCommand);
+
Object result;
// Is there a local transaction associated with GTX ?
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -21,21 +21,6 @@
*/
package org.jboss.cache.marshall;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Region;
-import org.jboss.cache.Region.Status;
-import org.jboss.cache.buddyreplication.GravitateResult;
-import org.jboss.cache.commands.CommandsFactory;
-import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.optimistic.DefaultDataVersion;
-import org.jboss.cache.transaction.GlobalTransaction;
-import org.jboss.cache.util.FastCopyHashMap;
-import org.jboss.cache.util.Immutables;
-import org.jgroups.Address;
-import org.jgroups.stack.IpAddress;
-
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -53,6 +38,23 @@
import java.util.TreeMap;
import java.util.TreeSet;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Region;
+import org.jboss.cache.Region.Status;
+import org.jboss.cache.buddyreplication.GravitateResult;
+import org.jboss.cache.commands.CommandsFactory;
+import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.optimistic.DefaultDataVersion;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.transaction.TransactionLog.LogEntry;
+import org.jboss.cache.util.FastCopyHashMap;
+import org.jboss.cache.util.Immutables;
+import org.jgroups.Address;
+import org.jgroups.stack.IpAddress;
+
/**
* An enhanced marshaller for RPC calls between CacheImpl instances.
*
@@ -90,10 +92,12 @@
protected static final int MAGICNUMBER_FLOAT = 27;
protected static final int MAGICNUMBER_DOUBLE = 28;
protected static final int MAGICNUMBER_OBJECT = 29;
+ protected static final int MAGICNUMBER_TXLOG_ENTRY = 50;
protected static final int MAGICNUMBER_NULL = 99;
protected static final int MAGICNUMBER_SERIALIZABLE = 100;
protected static final int MAGICNUMBER_REF = 101;
+
protected static final InactiveRegionException IRE = new InactiveRegionException("Cannot unmarshall to an inactive region");
public CacheMarshaller200()
@@ -343,6 +347,11 @@
if (useRefs) writeReference(out, createReference(o, refMap));
marshallGlobalTransaction((GlobalTransaction) o, out, refMap);
}
+ else if (o instanceof LogEntry)
+ {
+ out.writeByte(MAGICNUMBER_TXLOG_ENTRY);
+ marshallLogEntry((LogEntry)o, out, refMap);
+ }
else if (o instanceof IpAddress)
{
out.writeByte(MAGICNUMBER_IPADDRESS);
@@ -455,6 +464,12 @@
}
}
+ private void marshallLogEntry(LogEntry log, ObjectOutputStream out, Map<Object, Integer> refMap) throws Exception
+ {
+ marshallObject(log.getTransaction(), out, refMap);
+ marshallObject(log.getModifications(), out, refMap);
+ }
+
private void marshallGravitateResult(GravitateResult gravitateResult, ObjectOutputStream out, Map<Object, Integer> refMap) throws Exception
{
marshallObject(gravitateResult.isDataFound(), out, refMap);
@@ -605,6 +620,8 @@
retVal = unmarshallGlobalTransaction(in, refMap);
if (useRefs) refMap.putReferencedObject(reference, retVal);
return retVal;
+ case MAGICNUMBER_TXLOG_ENTRY:
+ return unmarshallLogEntry(in, refMap);
case MAGICNUMBER_IPADDRESS:
retVal = unmarshallIpAddress(in);
return retVal;
@@ -666,6 +683,15 @@
throw new Exception("Unknown magic number " + magicNumber);
}
+ @SuppressWarnings("unchecked")
+ private Object unmarshallLogEntry(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
+ {
+ GlobalTransaction gtx = (GlobalTransaction)unmarshallObject(in, refMap);
+ List<WriteCommand> mods = (List<WriteCommand>)unmarshallObject(in, refMap);
+
+ return new LogEntry(gtx, mods);
+ }
+
private FastCopyHashMap unmarshallFastCopyHashMap(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
FastCopyHashMap map = new FastCopyHashMap();
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CommandAwareRpcDispatcher.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CommandAwareRpcDispatcher.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CommandAwareRpcDispatcher.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -21,6 +21,16 @@
*/
package org.jboss.cache.marshall;
+import java.io.NotSerializableException;
+import java.util.Vector;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
import org.jboss.cache.InvocationContext;
import org.jboss.cache.commands.ReplicableCommand;
import org.jboss.cache.commands.VisitableCommand;
@@ -31,7 +41,9 @@
import org.jboss.cache.factories.ComponentRegistry;
import org.jboss.cache.interceptors.InterceptorChain;
import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.lock.TimeoutException;
import org.jboss.cache.util.concurrent.BoundedExecutors;
+import org.jboss.cache.util.concurrent.ReclosableLatch;
import org.jboss.cache.util.concurrent.WithinThreadExecutor;
import org.jgroups.Address;
import org.jgroups.Channel;
@@ -44,16 +56,6 @@
import org.jgroups.util.Rsp;
import org.jgroups.util.RspList;
-import java.io.NotSerializableException;
-import java.util.Vector;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
/**
* A JGroups RPC dispatcher that knows how to deal with {@link org.jboss.cache.commands.ReplicableCommand}s.
*
@@ -69,24 +71,27 @@
private ExecutorService replicationProcessor;
private AtomicInteger replicationProcessorCount;
private boolean asyncSerial;
+ private Configuration configuration;
+ private ReclosableLatch flushGate;
private ReplicationObserver replicationObserver;
- public CommandAwareRpcDispatcher()
- {
- }
+ public CommandAwareRpcDispatcher() {}
- public CommandAwareRpcDispatcher(Channel channel, MessageListener l, MembershipListener l2, Object serverObj,
- InvocationContextContainer container, InterceptorChain interceptorChain,
- ComponentRegistry componentRegistry)
+ public CommandAwareRpcDispatcher(Channel channel, MessageListener l, MembershipListener l2,
+ Object serverObj, InvocationContextContainer container, InterceptorChain interceptorChain,
+ ComponentRegistry componentRegistry, ReclosableLatch flushGate)
{
super(channel, l, l2, serverObj);
this.invocationContextContainer = container;
this.componentRegistry = componentRegistry;
this.interceptorChain = interceptorChain;
+ this.flushGate = flushGate;
+
trace = log.isTraceEnabled();
// what sort of a repl processor do we need?
Configuration c = componentRegistry.getComponent(Configuration.class);
+ this.configuration = c;
replicationProcessor = c.getRuntimeConfig().getAsyncSerializationExecutor();
if (c.getCacheMode().isSynchronous() ||
(replicationProcessor == null && c.getSerializationExecutorPoolSize() < 1) || requireSyncMarshalling(c)) // if an executor has not been injected and the pool size is set
@@ -125,7 +130,7 @@
/**
* Serial(sync) marshalling should be enabled for async optimistic caches. That is because optimistic async is a 2PC,
* which might cause the Commit command to be send before the Prepare command, so replication will fail. This is not
- * the same for async <b>pessimistic/mvcc</b> replication, as this uses a 1PC.
+ * the same for async <b>pessimistic/mvcc</b> replication, as this uses a 1PC.
*/
private boolean requireSyncMarshalling(Configuration c)
{
@@ -253,6 +258,11 @@
if (cmd == null) throw new NullPointerException("Unable to execute a null command! Message was " + req);
if (trace) log.trace("Executing command: " + cmd + " [sender=" + req.getSrc() + "]");
+ if (channel.flushSupported() && !flushGate.await(configuration.getStateRetrievalTimeout(), TimeUnit.MILLISECONDS))
+ {
+ throw new TimeoutException("State retrieval timed out waiting for flush unblock. (timeout = " + configuration.getStateRetrievalTimeout() + " millis) ");
+ }
+
if (cmd instanceof VisitableCommand)
{
InvocationContext ctx = invocationContextContainer.get();
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -25,6 +25,7 @@
import org.jboss.cache.factories.ComponentRegistry;
import org.jboss.cache.interceptors.InterceptorChain;
import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.util.concurrent.ReclosableLatch;
import org.jgroups.Channel;
import org.jgroups.MembershipListener;
import org.jgroups.Message;
@@ -46,9 +47,9 @@
*/
public InactiveRegionAwareRpcDispatcher(Channel channel, MessageListener l, MembershipListener l2, Object serverObj,
InvocationContextContainer container, InterceptorChain interceptorChain,
- ComponentRegistry componentRegistry)
+ ComponentRegistry componentRegistry, ReclosableLatch flushBlockGate)
{
- super(channel, l, l2, serverObj, container, interceptorChain, componentRegistry);
+ super(channel, l, l2, serverObj, container, interceptorChain, componentRegistry, flushBlockGate);
}
@Override
Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferGenerator.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -21,25 +21,29 @@
*/
package org.jboss.cache.statetransfer;
+import java.io.ObjectOutputStream;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
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.Fqn;
import org.jboss.cache.InternalNode;
import org.jboss.cache.Node;
+import org.jboss.cache.RPCManager;
import org.jboss.cache.Version;
+import org.jboss.cache.config.Configuration;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.marshall.NodeData;
import org.jboss.cache.marshall.NodeDataExceptionMarker;
+import org.jboss.cache.transaction.TransactionLog;
-import java.io.ObjectOutputStream;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
public class DefaultStateTransferGenerator implements StateTransferGenerator
{
@@ -48,13 +52,27 @@
private Log log = LogFactory.getLog(getClass().getName());
private CacheSPI cache;
+ private RPCManager rpcManager;
private Set<Fqn> internalFqns;
+ private boolean nonBlocking;
+ private long flushTimeout;
+ private int maxNonProgressingLogWrites = 5;
+ private TransactionLog txLog;
+
+
+
@Inject
- public void inject(CacheSPI cache)
+ public void inject(CacheSPI cache, RPCManager rpcManager, Configuration configuration, TransactionLog txLog)
{
this.cache = cache;
+ this.nonBlocking = true;
+
+ this.flushTimeout = configuration.getStateRetrievalTimeout();
+ this.nonBlocking = configuration.isNonBlockingStateTransfer();
+ this.txLog = txLog;
+ this.rpcManager = rpcManager;
}
@Start(priority = 14)
@@ -72,6 +90,16 @@
cache.getMarshaller().objectToObjectStream(STATE_TRANSFER_VERSION, out);
if (generateTransient)
{
+ if (nonBlocking)
+ {
+ if (! txLog.activate())
+ throw new CacheException("Busy performing state transfer for someone else");
+
+ if (log.isTraceEnabled())
+ log.trace("Transaction log activated!");
+
+ }
+
//transient + marker
if (log.isTraceEnabled())
{
@@ -128,12 +156,49 @@
}
}
delimitStream(out);
+
+ if (nonBlocking && generateTransient)
+ {
+ for (int nonProgress = 0, size = txLog.size(); nonProgress < maxNonProgressingLogWrites && size > 0;)
+ {
+ if (log.isTraceEnabled())
+ log.trace("Tx Log remaining entries = " + size);
+ txLog.writeCommitLog(cache.getMarshaller(), out);
+ int newSize = txLog.size();
+
+ // If size did not decrease then we did not make progress, and could be wasting
+ // our time. Limit this to the specified max.
+ if (newSize >= size)
+ nonProgress++;
+
+ size = newSize;
+ }
+
+ // Signal to sender that we need a flush to get a consistent view
+ // of the remaining transactions.
+ delimitStream(out);
+ out.flush();
+ rpcManager.waitForFlush(flushTimeout);
+
+ // Write remaining transactions
+ txLog.writeCommitLog(cache.getMarshaller(), out);
+ delimitStream(out);
+
+ // Write all non-completed prepares
+ txLog.writePendingPrepares(cache.getMarshaller(), out);
+ delimitStream(out);
+ }
+
}
catch (Exception e)
{
cache.getMarshaller().objectToObjectStream(new NodeDataExceptionMarker(e, cache.getLocalAddress()), out);
throw e;
}
+ finally
+ {
+ txLog.deactivate();
+ }
}
private Fqn getFqn(Object o)
Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -21,6 +21,16 @@
*/
package org.jboss.cache.statetransfer;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.CacheException;
@@ -30,26 +40,27 @@
import org.jboss.cache.InvocationContext;
import org.jboss.cache.Node;
import org.jboss.cache.NodeSPI;
+import org.jboss.cache.RPCManager;
import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.ComponentRegistry;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.interceptors.InterceptorChain;
+import org.jboss.cache.invocation.InvocationContextContainer;
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.loader.CacheLoaderManager;
import org.jboss.cache.marshall.NodeData;
import org.jboss.cache.marshall.NodeDataExceptionMarker;
import org.jboss.cache.marshall.NodeDataMarker;
import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.transaction.TransactionLog;
+import org.jboss.cache.transaction.TransactionLog.LogEntry;
+import org.jgroups.Address;
+import org.jgroups.Channel;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
public class DefaultStateTransferIntegrator implements StateTransferIntegrator
{
@@ -60,13 +71,25 @@
private Set<Fqn> internalFqns;
private Configuration cfg;
+ private RPCManager manager;
+ private TransactionLog txLog;
private boolean needToPersistState; // for JBCACHE-131
+ private boolean nonBlocking;
+ private InvocationContextContainer container;
+ private InterceptorChain chain;
+ private ComponentRegistry registry;
@Inject
- public void inject(CacheSPI<?, ?> cache, Configuration cfg)
+ public void inject(CacheSPI<?, ?> cache, Configuration cfg, RPCManager rpcManager, TransactionLog txLog, InvocationContextContainer container, InterceptorChain chain, ComponentRegistry registry)
{
this.cache = cache;
this.cfg = cfg;
+ this.manager = rpcManager;
+ this.nonBlocking = cfg.isNonBlockingStateTransfer();
+ this.txLog = txLog;
+ this.container = container;
+ this.chain = chain;
+ this.registry = registry;
}
@Start(priority = 14)
@@ -89,8 +112,103 @@
{
integratePersistentState(ois, targetRoot);
}
+
+ // Delimiter
+ verifyMarker(cache.getMarshaller().objectFromObjectStream(ois));
+
+ if (nonBlocking)
+ integrateTxLog(ois);
}
+ private void integrateTxLog(ObjectInputStream ois) throws Exception
+ {
+ if (trace)
+ log.trace("Integrating transaction log");
+
+ processCommitLog(ois);
+
+ Channel channel = manager.getChannel();
+
+ List<Address> targets = new ArrayList<Address>(2);
+ targets.add(channel.getLocalAddress());
+ targets.add(manager.getLastStateTransferSource());
+
+ if (trace)
+ log.trace("Flushing targets: " + targets);
+
+ if (!channel.startFlush(targets, false))
+ throw new CacheException("Could not flush channel! State-transfer failed!");
+
+ try
+ {
+ if (trace)
+ log.trace("Retrieving/Applying post-flush commits");
+ processCommitLog(ois);
+
+ if (trace)
+ log.trace("Retrieving/Applying pending prepares");
+ Object object = cache.getMarshaller().objectFromObjectStream(ois);
+ while (object instanceof PrepareCommand)
+ {
+ PrepareCommand command = (PrepareCommand)object;
+ if (! txLog.hasPendingPrepare(command))
+ {
+ InvocationContext ctx = container.get();
+ ctx.setOriginLocal(false);
+ ctx.getOptionOverrides().setCacheModeLocal(true);
+ ctx.getOptionOverrides().setSkipCacheStatusCheck(true);
+ chain.invoke(ctx, command);
+ }
+ object = cache.getMarshaller().objectFromObjectStream(ois);
+ }
+ verifyMarker(object);
+
+ // Block all remote commands once transfer is complete,
+ // and before FLUSH completes
+ registry.setBlockInStarting(true);
+ }
+ finally
+ {
+ if (trace)
+ log.trace("Stopping flush");
+ channel.stopFlush(targets);
+ }
+ }
+
+ private void processCommitLog(ObjectInputStream ois) throws Exception
+ {
+ Object object = cache.getMarshaller().objectFromObjectStream(ois);
+ while (object instanceof LogEntry)
+ {
+ List<WriteCommand> mods = ((LogEntry)object).getModifications();
+ log.trace("Mods = " + mods);
+ for (WriteCommand mod : mods)
+ {
+ InvocationContext ctx = container.get();
+ ctx.setOriginLocal(false);
+ ctx.getOptionOverrides().setCacheModeLocal(true);
+ ctx.getOptionOverrides().setSkipCacheStatusCheck(true);
+ chain.invoke(ctx, mod);
+ }
+
+ object = cache.getMarshaller().objectFromObjectStream(ois);
+ }
+ verifyMarker(object);
+ }
+
+ private void verifyMarker(Object object)
+ {
+ if (object instanceof NodeDataExceptionMarker)
+ {
+ NodeDataExceptionMarker e = (NodeDataExceptionMarker)object;
+ throw new CacheException("Error in state transfer stream", e.getCause());
+ }
+ else if (! (object instanceof NodeDataMarker))
+ {
+ throw new CacheException("Invalid object unmarshalled");
+ }
+ }
+
protected void integrateTransientState(ObjectInputStream in, InternalNode target) throws Exception
{
boolean transientSet = false;
Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferManager.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferManager.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -51,7 +51,6 @@
protected static final boolean trace = log.isTraceEnabled();
public static final NodeData STREAMING_DELIMITER_NODE = new NodeDataMarker();
-
public static final String PARTIAL_STATE_DELIMITER = "_PARTIAL_STATE_DELIMITER";
protected CacheSPI cache;
Added: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionLog.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionLog.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionLog.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -0,0 +1,179 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.transaction;
+
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.commands.tx.PrepareCommand;
+import org.jboss.cache.marshall.Marshaller;
+
+/**
+ * Logs transactions and writes for Non-Blocking State Transfer
+ *
+ * @author Jason T. Greene
+ */
+public class TransactionLog
+{
+ private final Map<GlobalTransaction, PrepareCommand> pendingPrepares = new ConcurrentHashMap<GlobalTransaction, PrepareCommand>();
+ private final BlockingQueue<LogEntry> entries = new LinkedBlockingQueue<LogEntry>();
+ private AtomicBoolean active = new AtomicBoolean();
+
+ public static class LogEntry
+ {
+ private final GlobalTransaction transaction;
+ private final List<WriteCommand> modifications;
+
+ public LogEntry(GlobalTransaction transaction, List<WriteCommand> modifications)
+ {
+ this.transaction = transaction;
+ this.modifications = modifications;
+ }
+
+ public GlobalTransaction getTransaction()
+ {
+ return transaction;
+ }
+
+ public List<WriteCommand> getModifications()
+ {
+ return modifications;
+ }
+ }
+
+ private Log log = LogFactory.getLog(getClass().getName());
+
+ public void logPrepare(PrepareCommand command)
+ {
+ pendingPrepares.put(command.getGlobalTransaction(), command);
+ }
+
+ public void logCommit(GlobalTransaction gtx)
+ {
+ PrepareCommand command = pendingPrepares.remove(gtx);
+ if (command == null)
+ {
+ log.error("Could not find matching prepare for commit: " + gtx);
+ return;
+ }
+
+ addEntry(new LogEntry(gtx, command.getModifications()));
+ }
+
+ private void addEntry(LogEntry entry)
+ {
+ if (! isActive())
+ return;
+
+ for (;;)
+ {
+ try
+ {
+ if (log.isTraceEnabled())
+ log.trace("Added commit entry to tx log" + entry);
+
+ entries.put(entry);
+ break;
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ public void logOnePhaseCommit(GlobalTransaction gtx, List<WriteCommand> modifications)
+ {
+ // Just in case...
+ if (gtx != null) pendingPrepares.remove(gtx);
+ addEntry(new LogEntry(gtx, modifications));
+ }
+
+ public void logNoTxWrite(WriteCommand write)
+ {
+ if (! isActive())
+ return;
+
+ ArrayList<WriteCommand> list = new ArrayList<WriteCommand>();
+ list.add(write);
+ addEntry(new LogEntry(null, list));
+ }
+
+ public void rollback(GlobalTransaction gtx)
+ {
+ pendingPrepares.remove(gtx);
+ }
+
+ public boolean isActive()
+ {
+ return active.get();
+ }
+
+ public boolean activate()
+ {
+ return active.compareAndSet(false, true);
+ }
+
+ public void deactivate()
+ {
+ active.set(false);
+ entries.clear();
+ }
+
+ public int size()
+ {
+ return entries.size();
+ }
+
+ public void writeCommitLog(Marshaller marshaller, ObjectOutputStream out) throws Exception
+ {
+ List<LogEntry> buffer = new ArrayList<LogEntry>(10);
+
+ while (entries.drainTo(buffer, 10) > 0)
+ {
+ for (LogEntry entry : buffer)
+ marshaller.objectToObjectStream(entry, out);
+
+ buffer.clear();
+ }
+ }
+
+ public void writePendingPrepares(Marshaller marshaller, ObjectOutputStream out) throws Exception
+ {
+ for (PrepareCommand entry : pendingPrepares.values())
+ marshaller.objectToObjectStream(entry, out);
+ }
+
+ public boolean hasPendingPrepare(PrepareCommand command)
+ {
+ return pendingPrepares.containsKey(command.getGlobalTransaction());
+ }
+}
Property changes on: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionLog.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -0,0 +1,247 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.statetransfer;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.UnitTestCacheFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestConfigurationFactory;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.Test;
+
+@Test(groups="functional")
+public class NonBlockingStateTransferTest
+{
+ public static final Fqn A = Fqn.fromString("/a");
+ public static final Fqn B = Fqn.fromString("/b");
+ public static final Fqn C = Fqn.fromString("/c");
+ protected static final String ADDRESS_CLASSNAME = "org.jboss.cache.marshall.data.Address";
+ protected static final String PERSON_CLASSNAME = "org.jboss.cache.marshall.data.Person";
+ public static final Fqn A_B = Fqn.fromString("/a/b");
+ public static final Fqn A_C = Fqn.fromString("/a/c");
+ public static final Fqn A_D = Fqn.fromString("/a/d");
+ public static final String JOE = "JOE";
+ public static final String BOB = "BOB";
+ public static final String JANE = "JANE";
+ public static final Integer TWENTY = 20;
+ public static final Integer FORTY = 40;
+
+ public static class DelayTransfer implements Serializable
+ {
+ private transient int count;
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException
+ {
+ out.defaultWriteObject();
+
+ // RPC is first serialization, ST is second
+ if (count++ == 0)
+ return;
+
+ try
+ {
+ Thread.sleep(2000);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+
+ }
+ private static class WritingRunner implements Runnable
+ {
+ private final Cache<Object,Object> cache;
+ private final boolean tx;
+ private volatile boolean stop;
+ private volatile int result;
+
+ WritingRunner(Cache<Object, Object> cache, boolean tx)
+ {
+ this.cache = cache;
+ this.tx = tx;
+ }
+
+ public int result()
+ {
+ return result;
+ }
+
+ public void run()
+ {
+ int c = 0;
+ while (!stop)
+ {
+ try
+ {
+ if (tx)
+ cache.getConfiguration().getRuntimeConfig().getTransactionManager().begin();
+ cache.put("/test" + c, "test", c++);
+ if (tx)
+ cache.getConfiguration().getRuntimeConfig().getTransactionManager().commit();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ result = c;
+ }
+
+ public void stop()
+ {
+ stop = true;
+ }
+ }
+
+ private CacheSPI<Object, Object> createCache(String name)
+ {
+ Configuration config = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+ config.setClusterName(name + "-" + Thread.currentThread().getName());
+ config.setNonBlockingStateTransfer(true);
+ CacheSPI<Object, Object> cache = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(config, false, getClass());
+
+ // Use marshaller
+
+ cache.create();
+ cache.start();
+ return cache;
+ }
+
+ public void testInitialStateTransfer() throws Exception
+ {
+ CacheSPI<Object, Object> cache1 = createCache("nbst");
+
+ writeInitialData(cache1);
+
+ CacheSPI<Object, Object> cache2 = createCache("nbst");
+
+ // Pause to give caches time to see each other
+ TestingUtil.blockUntilViewsReceived(new CacheSPI[]{cache1, cache2}, 60000);
+
+ verifyInitialData(cache2);
+
+ TestingUtil.killCaches(cache1, cache2);
+ }
+
+
+ public void testSTWithThirdWritingNonTxCache() throws Exception
+ {
+ thirdWritingCacheTest(false, "nbst1");
+ }
+
+ public void testSTWithThirdWritingTxCache() throws Exception
+ {
+ thirdWritingCacheTest(true, "nbst2");
+ }
+
+ public void testSTWithWritingNonTxThread() throws Exception
+ {
+ writingThreadTest(false, "nbst3");
+ }
+
+ public void testSTWithWritingTxThread() throws Exception
+ {
+ writingThreadTest(true, "nbst4");
+ }
+
+
+ private void thirdWritingCacheTest(boolean tx, String name) throws InterruptedException
+ {
+ final CacheSPI<Object, Object> cache1 = createCache(name);
+ final CacheSPI<Object, Object> cache3 = createCache(name);
+
+ writeInitialData(cache1);
+
+ // Delay the transient copy, so that we get a more thorough log test
+ cache1.put("/delay", "delay", new DelayTransfer());
+
+ WritingRunner writer = new WritingRunner(cache3, tx);
+ Thread writerThread = new Thread(writer);
+ writerThread.start();
+
+ CacheSPI<Object, Object> cache2 = createCache(name);
+
+ // Pause to give caches time to see each other
+ TestingUtil.blockUntilViewsReceived(new CacheSPI[]{cache1, cache2, cache3}, 60000);
+
+ writer.stop();
+ writerThread.join();
+
+ verifyInitialData(cache2);
+
+ int count = writer.result();
+
+ for (int c = 0; c < count; c++)
+ assertEquals(c, cache2.get("/test" + c, "test"));
+
+ TestingUtil.killCaches(cache1, cache2, cache3);
+ }
+
+ private void verifyInitialData(CacheSPI<Object, Object> cache2)
+ {
+ assertEquals("Incorrect name for /a/b", JOE, cache2.get(A_B, "name"));
+ assertEquals("Incorrect age for /a/b", TWENTY, cache2.get(A_B, "age"));
+ assertEquals("Incorrect name for /a/c", BOB, cache2.get(A_C, "name"));
+ assertEquals("Incorrect age for /a/c", FORTY, cache2.get(A_C, "age"));
+ }
+
+ private void writeInitialData(final CacheSPI<Object, Object> cache1)
+ {
+ cache1.put(A_B, "name", JOE);
+ cache1.put(A_B, "age", TWENTY);
+ cache1.put(A_C, "name", BOB);
+ cache1.put(A_C, "age", FORTY);
+ }
+
+ private void writingThreadTest(boolean tx, String name) throws InterruptedException
+ {
+ final CacheSPI<Object, Object> cache1 = createCache(name);
+
+ writeInitialData(cache1);
+
+ // Delay the transient copy, so that we get a more thorough log test
+ cache1.put("/delay", "delay", new DelayTransfer());
+
+ WritingRunner writer = new WritingRunner(cache1, tx);
+ Thread writerThread = new Thread(writer);
+ writerThread.start();
+
+ CacheSPI<Object, Object> cache2 = createCache(name);
+
+ // Pause to give caches time to see each other
+ TestingUtil.blockUntilViewsReceived(new CacheSPI[]{cache1, cache2}, 60000);
+
+ writer.stop();
+ writerThread.join();
+
+ verifyInitialData(cache2);
+
+ int count = writer.result();
+
+ for (int c = 0; c < count; c++)
+ assertEquals(c, cache2.get("/test" + c, "test"));
+
+ TestingUtil.killCaches(cache1, cache2);
+ }
+}
Property changes on: core/trunk/src/test/java/org/jboss/cache/statetransfer/NonBlockingStateTransferTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: core/trunk/src/test/java/org/jboss/cache/transaction/PrepareCommitContentionTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/transaction/PrepareCommitContentionTest.java 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/test/java/org/jboss/cache/transaction/PrepareCommitContentionTest.java 2009-02-04 23:54:51 UTC (rev 7649)
@@ -156,5 +156,15 @@
{
return delegate.getChannel();
}
+
+ public Address getLastStateTransferSource()
+ {
+ return delegate.getLastStateTransferSource();
+ }
+
+ public void waitForFlush(long timeout)
+ {
+ delegate.waitForFlush(timeout);
+ }
}
}
Modified: core/trunk/src/test/resources/log4j.xml
===================================================================
--- core/trunk/src/test/resources/log4j.xml 2009-02-04 23:48:43 UTC (rev 7648)
+++ core/trunk/src/test/resources/log4j.xml 2009-02-04 23:54:51 UTC (rev 7649)
@@ -57,7 +57,7 @@
<!-- ================ -->
<category name="org.jboss.cache">
- <priority value="WARN"/>
+ <priority value="TRACE"/>
</category>
<!-- these two are in separate sections since they
15 years, 10 months
JBoss Cache SVN: r7648 - core/trunk/src/test/java/org/jboss/cache/statetransfer.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2009-02-04 18:48:43 -0500 (Wed, 04 Feb 2009)
New Revision: 7648
Modified:
core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java
Log:
re-enabled and simplified tests
Modified: core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java 2009-02-04 23:39:11 UTC (rev 7647)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java 2009-02-04 23:48:43 UTC (rev 7648)
@@ -12,10 +12,11 @@
import org.jboss.cache.CacheSPI;
import org.jboss.cache.UnitTestCacheFactory;
import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
import org.jboss.cache.Region;
import org.jboss.cache.RegionImpl;
+import org.jboss.cache.eviction.LRUAlgorithmConfig;
import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.EvictionRegionConfig;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
import org.jboss.cache.factories.UnitTestConfigurationFactory;
@@ -27,7 +28,6 @@
import org.testng.annotations.Test;
import java.util.Random;
-import java.util.Set;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -38,7 +38,7 @@
*
* @author <a href="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
*/
-@Test(groups = "functional", enabled = false, testName = "statetransfer.StateTransferConcurrencyTest")
+@Test(groups = "functional", testName = "statetransfer.StateTransferConcurrencyTest")
public class StateTransferConcurrencyTest extends StateTransferTestBase
{
protected String getReplicationVersion()
@@ -48,18 +48,6 @@
/**
* Tests concurrent activation of the same subtree by multiple nodes in a
- * REPL_SYNC environment. The idea is to see what would happen with a
- * farmed deployment. See <code>concurrentActivationTest</code> for details.
- *
- * @throws Exception
- */
- public void testConcurrentActivationSync() throws Exception
- {
- concurrentActivationTest(true);
- }
-
- /**
- * Tests concurrent activation of the same subtree by multiple nodes in a
* REPL_ASYNC environment. The idea is to see what would happen with a
* farmed deployment. See <code>concurrentActivationTest</code> for details.
*
@@ -71,25 +59,23 @@
}
/**
- * Starts 5 caches and then concurrently activates the same region under
- * all 5, causing each to attempt a partial state transfer from the others.
+ * //todo - create a mvn profile and allow tests to run on more than 2 caches
+ * Starts 2 caches and then concurrently activates the same region under
+ * all 2, causing each to attempt a partial state transfer from the other.
* As soon as each cache has activated its region, it does a put to a node
- * in the region, thus complicating the lives of the other caches trying
+ * in the region, thus complicating the lives of the other cache trying
* to get partial state.
* <p/>
* Failure condition is if any node sees an exception or if the final state
* of all caches is not consistent.
- *
- * @param sync use REPL_SYNC or REPL_ASYNC
- * @throws Exception
*/
private void concurrentActivationTest(boolean sync)
{
- String[] names = {"A", "B", "C", "D", "E"};
+ String[] names = {"A", "B"};
int count = names.length;
CacheActivator[] activators = new CacheActivator[count];
-
+ long start = System.currentTimeMillis();
try
{
// Create a semaphore and take all its tickets
@@ -100,7 +86,7 @@
CacheSPI[] caches = new CacheSPI[count];
for (int i = 0; i < count; i++)
{
- activators[i] = new CacheActivator(semaphore, names[i], sync, caches);
+ activators[i] = new CacheActivator(semaphore, names[i], sync);
caches[i] = activators[i].getCacheSPI();
activators[i].start();
}
@@ -128,6 +114,8 @@
waitTillAllReplicationsFinish(count, caches);
}
+ System.out.println("System.currentTimeMillis()-st = " + (System.currentTimeMillis()-start));
+
// Ensure the caches held by the activators see all the values
for (int i = 0; i < count; i++)
{
@@ -193,19 +181,19 @@
private void concurrentActivationTest2(boolean sync)
{
String[] names = {"A", "B"};
- int count = names.length;
- int regionsToActivate = 15;
- int sleepTimeBetweenNodeStarts = 10000;
- StaggeredWebDeployerActivator[] activators = new StaggeredWebDeployerActivator[count];
+ int cacheCount = names.length;
+ int regionsToActivate = 3;
+ int sleepTimeBetweenNodeStarts = 1000;
+ StaggeredWebDeployerActivator[] activators = new StaggeredWebDeployerActivator[cacheCount];
try
{
// Create a semaphore and take all its tickets
- Semaphore semaphore = new Semaphore(count);
- semaphore.acquire(count);
+ Semaphore semaphore = new Semaphore(cacheCount);
+ semaphore.acquire(cacheCount);
// Create activation threads that will block on the semaphore
- CacheSPI[] caches = new CacheSPI[count];
- for (int i = 0; i < count; i++)
+ CacheSPI[] caches = new CacheSPI[cacheCount];
+ for (int i = 0; i < cacheCount; i++)
{
activators[i] = new StaggeredWebDeployerActivator(semaphore, names[i], sync, regionsToActivate);
caches[i] = activators[i].getCacheSPI();
@@ -225,7 +213,7 @@
// Reacquire the semaphore tickets; when we have them all
// we know the threads are done
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < cacheCount; i++)
{
boolean acquired = semaphore.tryAcquire(60, TimeUnit.SECONDS);
if (!acquired)
@@ -237,11 +225,11 @@
// Sleep to allow any async calls to clear
if (!sync)
{
- waitTillAllReplicationsFinish(count, caches);
+ waitTillAllReplicationsFinish(cacheCount, caches);
}
// Ensure the caches held by the activators see all the values
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < cacheCount; i++)
{
Exception aException = activators[i].getException();
boolean gotUnexpectedException = aException != null
@@ -266,7 +254,7 @@
}
finally
{
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < cacheCount; i++)
{
activators[i].cleanup();
}
@@ -348,7 +336,7 @@
*/
private void concurrentUseTest(boolean sync) throws Exception
{
- String[] names = {"B", "C", "D", "E"};
+ String[] names = {"B"};
int count = names.length;
CacheStressor[] stressors = new CacheStressor[count];
@@ -467,29 +455,23 @@
*/
public void testEvictionSeesStateTransfer() throws Exception
{
- Configuration c = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, true);
+ Configuration c = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, false);
additionalConfiguration(c);
Cache<Object, Object> cache1 = new UnitTestCacheFactory<Object, Object>().createCache(c, getClass());
caches.put("evict1", cache1);
-
cache1.put(Fqn.fromString("/a/b/c"), "key", "value");
c = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, true);
additionalConfiguration(c);
+ c.getEvictionConfig().setWakeupInterval(-1);
Cache<Object, Object> cache2 = new UnitTestCacheFactory<Object, Object>().createCache(c, getClass());
caches.put("evict2", cache2);
RegionImpl region = (RegionImpl) cache2.getRegion(Fqn.ROOT, false);
// We expect a VISIT event for / and ADD events for /a, /a/b and /a/b/c
int nodeEventQueueSize = region.getEvictionEventQueue().size();
- int i = 0;
- int events = nodeEventQueueSize;
- while (events > 0)
- {
- events = region.getEvictionEventQueue().size();
- }
boolean mvcc = cache2.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.MVCC;
- assertEquals("Saw the expected number of node events", mvcc ? 5 : 3, nodeEventQueueSize);
+ assertEquals("Saw the expected number of node events", mvcc ? 6 : 4, nodeEventQueueSize);
}
/**
@@ -497,183 +479,44 @@
*/
public void testEvictionAfterStateTransfer() throws Exception
{
- Configuration c = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, true);
+ Configuration c = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, false);
additionalConfiguration(c);
Cache<Object, Object> cache1 = new UnitTestCacheFactory<Object, Object>().createCache(c, getClass());
caches.put("evict1", cache1);
- for (int i = 0; i < 25000; i++)
+ for (int i = 0; i < 10; i++)
{
- cache1.put(Fqn.fromString("/org/jboss/data/" + i), "key", "base" + i);
- if (i < 5)
- {
- cache1.put(Fqn.fromString("/org/jboss/test/data/" + i), "key", "data" + i);
- if (i == 0)
- {
- cache1.getRoot().getChild(Fqn.fromString("/org/jboss/data")).setResident(true); //so that it won't be counted for eviction
- }
- }
+ cache1.put(Fqn.fromString("/org/jboss/test/data/" + i), "key", "data" + i);
}
- EvictionController ec1 = new EvictionController(cache1);
- ec1.startEviction();
- int childrenSize = cache1.getRoot().getChild(Fqn.fromString("/org/jboss/data")).getChildren().size();
- assert childrenSize == 5000 : "Expected 5000, saw " + childrenSize;
+ assert cache1.getRoot().getChild(Fqn.fromString("/org/jboss/test/data/")).getChildren().size() == 10;
c = UnitTestConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, true);
+ c.getEvictionConfig().setWakeupInterval(-1);
+ EvictionRegionConfig evictionRegionConfig = c.getEvictionConfig().getEvictionRegionConfig("/org/jboss/test/data");
+ LRUAlgorithmConfig evictionAlgorithmConfig = (LRUAlgorithmConfig) evictionRegionConfig.getEvictionAlgorithmConfig();
+ evictionAlgorithmConfig.setTimeToLive(-1);
additionalConfiguration(c);
final Cache<Object, Object> cache2 = new UnitTestCacheFactory<Object, Object>().createCache(c, getClass());
+ EvictionController ec2 = new EvictionController(cache2);
caches.put("evict2", cache2);
- Node<Object, Object> parent;// = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data"));
- parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/data"));
- Set children = parent.getChildren();
- //4999 because the root of the region will also be counted, as it is not resident
- assertTrue("Minimum number of base children transferred", children.size() >= 4999);
-
- // Sleep 2.5 secs so the nodes we are about to create in data won't
- // exceed the 4 sec TTL when eviction thread runs
- TestingUtil.sleepThread(2500);
-
- class Putter extends Thread
- {
- Cache<Object, Object> cache = null;
- boolean stopped = false;
- Exception ex = null;
-
- public void run()
- {
- int i = 25000;
- while (!stopped)
- {
- try
- {
- cache.put(Fqn.fromString("/org/jboss/data/" + i), "key", "base" + i);
- cache.put(Fqn.fromString("/org/jboss/test/data/" + i), "key", "data" + i);
- i++;
- }
- catch (Exception e)
- {
- ex = e;
- }
- }
- }
- }
- Putter p1 = new Putter();
- p1.cache = cache1;
- p1.start();
- Putter p2 = new Putter();
- p2.cache = cache2;
- p2.start();
-
- Random rnd = new Random();
- TestingUtil.sleepThread(rnd.nextInt(200));
-
- int maxCountBase = 0;
- int maxCountData = 0;
- boolean sawBaseDecrease = false;
- boolean sawDataDecrease = false;
- long start = System.currentTimeMillis();
- Node root = cache2.getRoot();
- while ((System.currentTimeMillis() - start) < 10000)
- {
- parent = root.getChild(Fqn.fromString("/org/jboss/test/data"));
- children = parent.getChildren();
- if (children != null)
- {
- int dataCount = children.size();
- if (dataCount < maxCountData)
- {
- sawDataDecrease = true;
- }
- else
- {
- maxCountData = dataCount;
- }
- }
-
- parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/data"));
- children = parent.getChildren();
- if (children != null)
- {
- int baseCount = children.size();
- if (baseCount < maxCountBase)
- {
- sawBaseDecrease = true;
- }
- else
- {
- maxCountBase = baseCount;
- }
- }
-
- if (sawDataDecrease && sawBaseDecrease)
- {
- break;
- }
-
- TestingUtil.sleepThread(50);
- }
-
- p1.stopped = true;
- p2.stopped = true;
- p1.join(1000);
- p2.join(1000);
-
- assertTrue("Saw data decrease", sawDataDecrease);
- assertTrue("Saw base decrease", sawBaseDecrease);
- assertNull("No exceptions in p1", p1.ex);
- assertNull("No exceptions in p2", p2.ex);
-
- EvictionController ec2 = new EvictionController(cache2);
+ assert cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data/")).getChildren().size() == 10;
ec2.startEviction();
-
- parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data"));
- children = parent.getChildren();
- if (children != null)
- {
- assertTrue("Excess children evicted", children.size() <= 5);
- }
- parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/data"));
- children = parent.getChildren();
- if (children != null)
- {
- assertTrue("Excess children evicted", children.size() <= 25000);
- }
-
- // Sleep more to let the eviction thread run again,
- // which will evict all data nodes due to their ttl of 4 secs
- ec2.evictRegionWithTimeToLive("/org/jboss/test/data");
-
- parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data"));
- if (parent != null)
- {
- children = parent.getChildren();
- if (children != null)
- {
- assertEquals("All data children evicted", 0, children.size());
- }
- }
+ assert cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data/")).getChildren().size() == 5;
}
private class CacheActivator extends CacheUser
{
-
- private CacheSPI[] caches;
-
- CacheActivator(Semaphore semaphore,
- String name,
- boolean sync, CacheSPI[] caches)
- throws Exception
+ CacheActivator(Semaphore semaphore, String name, boolean sync) throws Exception
{
super(semaphore, name, sync, false, 120000);
- this.caches = caches;
}
@SuppressWarnings("unchecked")
void useCache() throws Exception
{
- TestingUtil.sleepRandom(5000);
+ TestingUtil.sleepRandom(500);
createAndActivateRegion(cache, A_B);
Fqn childFqn = Fqn.fromRelativeElements(A_B, name);
cache.put(childFqn, "KEY", "VALUE");
@@ -690,11 +533,7 @@
int regionCount = 15;
- StaggeredWebDeployerActivator(Semaphore semaphore,
- String name,
- boolean sync,
- int regionCount)
- throws Exception
+ StaggeredWebDeployerActivator(Semaphore semaphore, String name, boolean sync, int regionCount) throws Exception
{
super(semaphore, name, sync, false);
this.regionCount = regionCount;
@@ -705,11 +544,8 @@
for (int i = 0; i < regionCount; i++)
{
createAndActivateRegion(cache, Fqn.fromString("/a/" + i));
-
Fqn childFqn = Fqn.fromString("/a/" + i + "/" + name);
cache.put(childFqn, "KEY", "VALUE");
-
- TestingUtil.sleepThread(1000);
}
}
15 years, 10 months
JBoss Cache SVN: r7647 - core/trunk/src/test/java/org/jboss/cache/factories.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2009-02-04 18:39:11 -0500 (Wed, 04 Feb 2009)
New Revision: 7647
Modified:
core/trunk/src/test/java/org/jboss/cache/factories/LifeCycleWithReplTest.java
Log:
removed tests condition as it relies on timeouts that do not stand in heavily threaded envs
Modified: core/trunk/src/test/java/org/jboss/cache/factories/LifeCycleWithReplTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/factories/LifeCycleWithReplTest.java 2009-02-04 23:37:41 UTC (rev 7646)
+++ core/trunk/src/test/java/org/jboss/cache/factories/LifeCycleWithReplTest.java 2009-02-04 23:39:11 UTC (rev 7647)
@@ -131,10 +131,7 @@
}
}.start();
- // should succeed but should take at least 1000ms.
- long startTime = System.currentTimeMillis();
first.put(Fqn.ROOT, "k", "v");
- assert System.currentTimeMillis() > (startTime + sleepTime) : "Should wait till second has STARTED state";
}
finally
{
15 years, 10 months