Skip to content

Commit

Permalink
Merge pull request #9 from codeforkjeff/fix-cme
Browse files Browse the repository at this point in the history
prevent ConcurrentModificationExceptions under high load in cache exp…
  • Loading branch information
codeforkjeff authored Oct 13, 2016
2 parents 26e5759 + cfac7be commit f02b38a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
8 changes: 4 additions & 4 deletions src/main/java/com/codefork/refine/Cache.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
* Simple cache implementation. This does NOT do any locking. Clients should
Expand All @@ -22,7 +22,7 @@ public class Cache<K, V> {

private int lifetime = DEFAULT_LIFETIME; // in seconds
private int maxSize = DEFAULT_MAXSIZE;
private HashMap<K, CachedValue> cacheMap = new HashMap<K, CachedValue>();
private ConcurrentHashMap<K, CachedValue> cacheMap = new ConcurrentHashMap<K, CachedValue>();

public int getLifetime() {
return lifetime;
Expand Down Expand Up @@ -82,7 +82,7 @@ public Cache<K, V> expireCache() {

// processing keys in descending timestamp order makes
// it easier to break out of the copy loop when we hit maxSize
final HashMap<K, CachedValue> oldMap = getMap();
final ConcurrentHashMap<K, CachedValue> oldMap = getMap();
K[] sorted = (K[]) oldMap.keySet().toArray();
Arrays.sort(sorted, new ReverseTimestampComparator());
int total = oldMap.size();
Expand Down Expand Up @@ -110,7 +110,7 @@ public Cache<K, V> expireCache() {
return newCache;
}

private HashMap<K, CachedValue> getMap() {
private ConcurrentHashMap<K, CachedValue> getMap() {
return cacheMap;
}

Expand Down
8 changes: 7 additions & 1 deletion src/main/java/com/codefork/refine/CacheExpire.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ public void run() {
try {
while(keepGoing) {
Thread.sleep(60000);
cacheManager.expireCache();
try {
cacheManager.expireCache();
} catch(Exception e) {
// if we don't catch here, a possibly intermittent or edge-case error
// causes the cache expire thread to die, and the cache will grow uncontrollably
log.error("Ignoring error that occurred in cacheManager.expireCache(): " + e.toString());
}
}
} catch (InterruptedException e) {
// noop
Expand Down

0 comments on commit f02b38a

Please sign in to comment.