* make sure to work around all ehcache diskcache problems, unexpected exceptions, inconsistency, etc

This commit is contained in:
Reinhard Pointner 2012-07-25 04:34:20 +00:00
parent 581fd76265
commit 3145245341
9 changed files with 148 additions and 90 deletions

View File

@ -0,0 +1,88 @@
package net.sourceforge.filebot;
import java.io.Serializable;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
public class Cache {
public static Cache getCache(String name) {
return new Cache(CacheManager.getInstance().getCache(name));
}
private final net.sf.ehcache.Cache cache;
protected Cache(net.sf.ehcache.Cache cache) {
this.cache = cache;
}
public void put(Object key, Object value) {
try {
cache.put(new Element(key, value));
} catch (Throwable e) {
Logger.getLogger(Cache.class.getName()).log(Level.WARNING, e.getMessage());
remove(key); // fail-safe
}
}
public <T> T get(Object key, Class<T> type) {
try {
Element element = cache.get(key);
if (element != null && key.equals(element.getKey())) {
return type.cast(element.getValue());
}
} catch (Exception e) {
Logger.getLogger(Cache.class.getName()).log(Level.WARNING, e.getMessage(), e);
remove(key); // fail-safe
}
return null;
}
public void remove(Object key) {
try {
cache.remove(key);
} catch (Exception e) {
Logger.getLogger(Cache.class.getName()).log(Level.WARNING, e.getMessage(), e);
}
}
public static class Key implements Serializable {
protected Object[] fields;
public Key(Object... fields) {
this.fields = fields;
}
@Override
public int hashCode() {
return Arrays.hashCode(fields);
}
@Override
public boolean equals(Object other) {
if (other instanceof Key) {
return Arrays.equals(this.fields, ((Key) other).fields);
}
return false;
}
}
}

View File

@ -22,9 +22,7 @@ import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.WebServices;
import net.sourceforge.filebot.hash.HashType;
import net.sourceforge.filebot.mediainfo.MediaInfo;
@ -589,15 +587,16 @@ public class MediaBindingBean {
private String crc32(File file) throws IOException, InterruptedException {
// try to get checksum from cache
Cache cache = CacheManager.getInstance().getCache("checksum");
Element element = cache.get(file);
if (element != null)
return (String) element.getValue();
Cache cache = Cache.getCache("checksum");
// compute and cache checksum
String hash = computeHash(file, HashType.SFV);
cache.put(new Element(file, hash));
String hash = cache.get(file, String.class);
if (hash != null) {
return hash;
}
// compute and cache checksum
hash = computeHash(file, HashType.SFV);
cache.put(file, hash);
return hash;
}
}

View File

@ -2,15 +2,14 @@
package net.sourceforge.filebot.web;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.Cache.Key;
public abstract class AbstractEpisodeListProvider implements EpisodeListProvider {
@ -38,6 +37,7 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
}
@Override
public List<SearchResult> search(String query, Locale locale) throws Exception {
ResultCache cache = getCache();
List<SearchResult> results = (cache != null) ? cache.getSearchResult(query, locale) : null;
@ -58,6 +58,7 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, SortOrder sortOrder, Locale locale) throws Exception {
ResultCache cache = getCache();
List<Episode> episodes = (cache != null) ? cache.getEpisodeList(searchResult, sortOrder, locale) : null;
@ -102,7 +103,7 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
public <T extends SearchResult> List<T> putSearchResult(String query, Locale locale, List<T> value) {
try {
cache.put(new Element(new Key(id, normalize(query), locale), value.toArray(new SearchResult[0])));
cache.put(new Key(id, normalize(query), locale), value.toArray(new SearchResult[0]));
} catch (Exception e) {
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
}
@ -113,9 +114,9 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
public List<SearchResult> getSearchResult(String query, Locale locale) {
try {
Element element = cache.get(new Key(id, normalize(query), locale));
if (element != null) {
return Arrays.asList(((SearchResult[]) element.getValue()));
SearchResult[] results = cache.get(new Key(id, normalize(query), locale), SearchResult[].class);
if (results != null) {
return Arrays.asList(results);
}
} catch (Exception e) {
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
@ -127,7 +128,7 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
public List<Episode> putEpisodeList(SearchResult key, SortOrder sortOrder, Locale locale, List<Episode> episodes) {
try {
cache.put(new Element(new Key(id, key, sortOrder, locale), episodes.toArray(new Episode[0])));
cache.put(new Key(id, key, sortOrder, locale), episodes.toArray(new Episode[0]));
} catch (Exception e) {
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
}
@ -138,9 +139,9 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
public List<Episode> getEpisodeList(SearchResult key, SortOrder sortOrder, Locale locale) {
try {
Element element = cache.get(new Key(id, key, sortOrder, locale));
if (element != null) {
return Arrays.asList((Episode[]) element.getValue());
Episode[] episodes = cache.get(new Key(id, key, sortOrder, locale), Episode[].class);
if (episodes != null) {
return Arrays.asList(episodes);
}
} catch (Exception e) {
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
@ -152,7 +153,7 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
public void putData(Object category, Object key, Locale locale, Object object) {
try {
cache.put(new Element(new Key(id, category, locale, key), object));
cache.put(new Key(id, category, locale, key), object);
} catch (Exception e) {
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage());
}
@ -161,9 +162,9 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
public <T> T getData(Object category, Object key, Locale locale, Class<T> type) {
try {
Element element = cache.get(new Key(id, category, locale, key));
if (element != null) {
return type.cast(element.getValue());
T value = cache.get(new Key(id, category, locale, key), type);
if (value != null) {
return value;
}
} catch (Exception e) {
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
@ -172,32 +173,6 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
return null;
}
private static class Key implements Serializable {
protected Object[] fields;
public Key(Object... fields) {
this.fields = fields;
}
@Override
public int hashCode() {
return Arrays.hashCode(fields);
}
@Override
public boolean equals(Object other) {
if (other instanceof Key) {
return Arrays.equals(this.fields, ((Key) other).fields);
}
return false;
}
}
}
}

View File

@ -23,12 +23,12 @@ import java.util.zip.GZIPInputStream;
import javax.swing.Icon;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.ResourceManager;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import net.sf.ehcache.CacheManager;
import net.sourceforge.filebot.ResourceManager;
public class AnidbClient extends AbstractEpisodeListProvider {
@ -70,7 +70,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
@Override
public ResultCache getCache() {
return new ResultCache(host, CacheManager.getInstance().getCache("web-persistent-datasource"));
return new ResultCache(host, Cache.getCache("web-persistent-datasource"));
}

View File

@ -53,6 +53,12 @@ public abstract class CachedResource<T extends Serializable> {
try {
element = getCache().get(cacheKey);
// sanity check ehcache diskcache problems
if (element != null && !cacheKey.equals(element.getKey().toString())) {
element = null;
}
if (element != null) {
lastUpdateTime = element.getLatestOfCreationAndUpdateTime();
}

View File

@ -17,13 +17,13 @@ import java.util.Set;
import javax.net.ssl.HttpsURLConnection;
import javax.swing.Icon;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.ResourceManager;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import net.sf.ehcache.CacheManager;
import net.sourceforge.filebot.ResourceManager;
public class SerienjunkiesClient extends AbstractEpisodeListProvider {
@ -57,7 +57,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
@Override
public ResultCache getCache() {
return new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
return new ResultCache(host, Cache.getCache("web-datasource"));
}

View File

@ -20,15 +20,13 @@ import java.util.regex.Pattern;
import javax.swing.Icon;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.ResourceManager;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sourceforge.filebot.ResourceManager;
public class SubsceneSubtitleClient implements SubtitleProvider {
@ -121,34 +119,28 @@ public class SubsceneSubtitleClient implements SubtitleProvider {
}
@SuppressWarnings("unchecked")
protected String getLanguageFilter(String languageName) throws IOException, SAXException {
if (languageName == null || languageName.isEmpty()) {
return null;
}
// try cache first
Cache cache = CacheManager.getInstance().getCache("web-persistent-datasource");
Cache cache = Cache.getCache("web-persistent-datasource");
String cacheKey = getClass().getName() + ".languageFilter";
try {
Element element = cache.get(cacheKey);
if (element != null) {
return (String) ((Map<?, ?>) element.getValue()).get(languageName.toLowerCase());
}
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getMessage());
Map<String, String> filters = cache.get(cacheKey, Map.class);
if (filters != null) {
return filters.get(languageName.toLowerCase());
}
// fetch new language filter data
Map<String, String> filters = getLanguageFilterMap();
filters = getLanguageFilterMap();
// update cache after sanity check
if (filters.size() > 42) {
try {
cache.put(new Element(cacheKey, filters));
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getMessage());
}
cache.put(cacheKey, filters);
} else {
Logger.getLogger(getClass().getName()).log(Level.WARNING, "Failed to scrape language filters: " + filters);
}

View File

@ -15,13 +15,13 @@ import java.util.Locale;
import javax.swing.Icon;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.ResourceManager;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import net.sf.ehcache.CacheManager;
import net.sourceforge.filebot.ResourceManager;
public class TVRageClient extends AbstractEpisodeListProvider {
@ -42,7 +42,7 @@ public class TVRageClient extends AbstractEpisodeListProvider {
@Override
public ResultCache getCache() {
return new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
return new ResultCache(host, Cache.getCache("web-datasource"));
}

View File

@ -29,15 +29,15 @@ import java.util.zip.ZipInputStream;
import javax.swing.Icon;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import net.sf.ehcache.CacheManager;
import net.sourceforge.filebot.Cache;
import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.web.TheTVDBClient.BannerDescriptor.BannerProperty;
import net.sourceforge.filebot.web.TheTVDBClient.SeriesInfo.SeriesProperty;
import net.sourceforge.tuned.FileUtilities;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class TheTVDBClient extends AbstractEpisodeListProvider {
@ -99,7 +99,7 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
@Override
public ResultCache getCache() {
return new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
return new ResultCache(host, Cache.getCache("web-datasource"));
}
@ -274,7 +274,7 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
// try cache first
try {
@SuppressWarnings("unchecked")
Map<MirrorType, String> cachedMirrors = (Map<MirrorType, String>) getCache().getData("mirrors", null, null, Map.class);
Map<MirrorType, String> cachedMirrors = getCache().getData("mirrors", null, null, Map.class);
if (cachedMirrors != null) {
mirrors.putAll(cachedMirrors);
return mirrors.get(mirrorType);
@ -479,7 +479,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
poster
}
protected Map<SeriesProperty, String> fields;
@ -762,7 +761,6 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
VignettePath
}
protected Map<BannerProperty, String> fields;