Commit 70fe97f4 authored by Tom Evans's avatar Tom Evans Committed by tevans

OF-588: Manage list of "local-only" caches separately from standard caches...

OF-588: Manage list of "local-only" caches separately from standard caches (forces local strategy where needed); also, explicitly clear caches when switching to/from cluster mode

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13381 b35dd754-fafc-0310-a699-88a17e54d16e
parent 6e5db356
...@@ -21,6 +21,7 @@ package org.jivesoftware.util.cache; ...@@ -21,6 +21,7 @@ package org.jivesoftware.util.cache;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -65,12 +66,8 @@ public class CacheFactory { ...@@ -65,12 +66,8 @@ public class CacheFactory {
* Storage for all caches that get created. * Storage for all caches that get created.
*/ */
private static Map<String, Cache> caches = new ConcurrentHashMap<String, Cache>(); private static Map<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
private static List<String> localOnly = Collections.synchronizedList(new ArrayList<String>());
/**
* Maps the cache to the strategy that created it.
*/
private static Map<String, CacheFactoryStrategy> strategyLookup = new ConcurrentHashMap<String, CacheFactoryStrategy>();
private static String localCacheFactoryClass; private static String localCacheFactoryClass;
private static String clusteredCacheFactoryClass; private static String clusteredCacheFactoryClass;
private static CacheFactoryStrategy cacheFactoryStrategy; private static CacheFactoryStrategy cacheFactoryStrategy;
...@@ -352,10 +349,9 @@ public class CacheFactory { ...@@ -352,10 +349,9 @@ public class CacheFactory {
if (cache != null) { if (cache != null) {
return cache; return cache;
} }
strategyLookup.put(name, cacheFactoryStrategy);
cache = (T) cacheFactoryStrategy.createCache(name); cache = (T) cacheFactoryStrategy.createCache(name);
log.info("Created default cache [" + clusteredCacheFactoryClass + "] for " + name); log.info("Created cache [" + cacheFactoryStrategy.getClass().getName() + "] for " + name);
return wrapCache(cache, name); return wrapCache(cache, name);
} }
...@@ -372,10 +368,10 @@ public class CacheFactory { ...@@ -372,10 +368,10 @@ public class CacheFactory {
if (cache != null) { if (cache != null) {
return cache; return cache;
} }
strategyLookup.put(name, localCacheFactoryStrategy);
cache = (T) localCacheFactoryStrategy.createCache(name); cache = (T) localCacheFactoryStrategy.createCache(name);
localOnly.add(name);
log.info("Created local cache [" + localCacheFactoryClass + "] for " + name); log.info("Created local-only cache [" + localCacheFactoryClass + "] for " + name);
return wrapCache(cache, name); return wrapCache(cache, name);
} }
...@@ -388,7 +384,12 @@ public class CacheFactory { ...@@ -388,7 +384,12 @@ public class CacheFactory {
public static void destroyCache(String name) { public static void destroyCache(String name) {
Cache cache = caches.remove(name); Cache cache = caches.remove(name);
if (cache != null) { if (cache != null) {
strategyLookup.get(name).destroyCache(cache); if (localOnly.contains(name)) {
localOnly.remove(name);
localCacheFactoryStrategy.destroyCache(cache);
} else {
cacheFactoryStrategy.destroyCache(cache);
}
} }
} }
...@@ -407,7 +408,11 @@ public class CacheFactory { ...@@ -407,7 +408,11 @@ public class CacheFactory {
* @return an existing lock on the specified key or creates a new one if none was found. * @return an existing lock on the specified key or creates a new one if none was found.
*/ */
public static Lock getLock(Object key, Cache cache) { public static Lock getLock(Object key, Cache cache) {
return strategyLookup.get(cache.getName()).getLock(key, cache); if (localOnly.contains(cache.getName())) {
return localCacheFactoryStrategy.getLock(key, cache);
} else {
return cacheFactoryStrategy.getLock(key, cache);
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
...@@ -502,23 +507,13 @@ public class CacheFactory { ...@@ -502,23 +507,13 @@ public class CacheFactory {
} }
/** /**
* Returns the maximum number of cluster members allowed. A value of 0 or 1 will * Returns the maximum number of cluster members allowed. A value of 0 will
* be returned when clustering is not allowed. * be returned when clustering is not allowed.
* *
* @return the maximum number of cluster members allowed or 0 or 1 if clustering is not allowed. * @return the maximum number of cluster members allowed or 0 if clustering is not allowed.
*/ */
public static int getMaxClusterNodes() { public static int getMaxClusterNodes() {
try { return cacheFactoryStrategy.getMaxClusterNodes();
CacheFactoryStrategy cacheFactory = (CacheFactoryStrategy) Class.forName(
clusteredCacheFactoryClass, true,
getClusteredCacheStrategyClassLoader()).newInstance();
return cacheFactory.getMaxClusterNodes();
} catch (ClassNotFoundException e) {
log.warn("Clustering implementation class " + clusteredCacheFactoryClass + " not found");
} catch (Exception e) {
log.error("Error instantiating clustered cache factory", e);
}
return 0;
} }
/** /**
* Invokes a task on other cluster members in an asynchronous fashion. The task will not be * Invokes a task on other cluster members in an asynchronous fashion. The task will not be
...@@ -576,18 +571,11 @@ public class CacheFactory { ...@@ -576,18 +571,11 @@ public class CacheFactory {
public static synchronized void initialize() throws InitializationException { public static synchronized void initialize() throws InitializationException {
try { try {
cacheFactoryStrategy = (CacheFactoryStrategy) Class localCacheFactoryStrategy = (CacheFactoryStrategy) Class.forName(localCacheFactoryClass).newInstance();
.forName(localCacheFactoryClass).newInstance(); cacheFactoryStrategy = localCacheFactoryStrategy;
localCacheFactoryStrategy = cacheFactoryStrategy; } catch (Exception e) {
} log.error("Failed to instantiate local cache factory strategy: " + localCacheFactoryClass, e);
catch (InstantiationException e) { throw new InitializationException(e);
throw new InitializationException(e);
}
catch (IllegalAccessException e) {
throw new InitializationException(e);
}
catch (ClassNotFoundException e) {
throw new InitializationException(e);
} }
} }
...@@ -683,15 +671,10 @@ public class CacheFactory { ...@@ -683,15 +671,10 @@ public class CacheFactory {
} }
public static void stopClustering() { public static void stopClustering() {
try { // Stop the cluster
// Stop the cluster cacheFactoryStrategy.stopCluster();
cacheFactoryStrategy.stopCluster(); // Set the strategy to local
// Set the strategy to local cacheFactoryStrategy = localCacheFactoryStrategy;
cacheFactoryStrategy = localCacheFactoryStrategy;
}
catch (Exception e) {
log.error("Unable to stop clustering - continuing in clustered mode", e);
}
} }
/** /**
...@@ -699,8 +682,11 @@ public class CacheFactory { ...@@ -699,8 +682,11 @@ public class CacheFactory {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void joinedCluster() { public static void joinedCluster() {
// Loop through local caches and switch them to clustered cache (migrate content) // Loop through local caches and switch them to clustered cache (purge content)
for (Cache cache : getAllCaches()) { for (Cache cache : getAllCaches()) {
// skip local-only caches
if (localOnly.contains(cache.getName())) continue;
cache.clear();
CacheWrapper cacheWrapper = ((CacheWrapper) cache); CacheWrapper cacheWrapper = ((CacheWrapper) cache);
Cache clusteredCache = cacheFactoryStrategy.createCache(cacheWrapper.getName()); Cache clusteredCache = cacheFactoryStrategy.createCache(cacheWrapper.getName());
cacheWrapper.setWrappedCache(clusteredCache); cacheWrapper.setWrappedCache(clusteredCache);
...@@ -715,18 +701,18 @@ public class CacheFactory { ...@@ -715,18 +701,18 @@ public class CacheFactory {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void leftCluster() { public static void leftCluster() {
clusteringStarted = false; clusteringStarted = false;
// Loop through clustered caches and change them to local caches (migrate content) // Loop through clustered caches and change them to local caches (purge content)
try { try {
cacheFactoryStrategy = localCacheFactoryStrategy; cacheFactoryStrategy = localCacheFactoryStrategy;
for (Cache cache : getAllCaches()) { for (Cache cache : getAllCaches()) {
// skip local-only caches
if (strategyLookup.get(cache.getName()) != localCacheFactoryStrategy) { if (localOnly.contains(cache.getName())) continue;
CacheWrapper cacheWrapper = ((CacheWrapper) cache); cache.clear();
Cache standaloneCache = cacheFactoryStrategy.createCache(cacheWrapper.getName()); CacheWrapper cacheWrapper = ((CacheWrapper) cache);
cacheWrapper.setWrappedCache(standaloneCache); Cache standaloneCache = cacheFactoryStrategy.createCache(cacheWrapper.getName());
} cacheWrapper.setWrappedCache(standaloneCache);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("Error reverting caches to local caches", e); log.error("Error reverting caches to local caches", e);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment