mirror of
https://github.com/mitb-archive/filebot
synced 2024-11-02 08:25:02 -04:00
Refactor ETag cache API
This commit is contained in:
parent
724e55485d
commit
5a2e9d3730
@ -45,9 +45,19 @@ public class Cache {
|
||||
}
|
||||
|
||||
private final net.sf.ehcache.Cache cache;
|
||||
private final CacheType cacheType;
|
||||
|
||||
public Cache(net.sf.ehcache.Cache cache) {
|
||||
public Cache(net.sf.ehcache.Cache cache, CacheType cacheType) {
|
||||
this.cache = cache;
|
||||
this.cacheType = cacheType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return cache.getName();
|
||||
}
|
||||
|
||||
public CacheType getCacheType() {
|
||||
return cacheType;
|
||||
}
|
||||
|
||||
public Object get(Object key) {
|
||||
@ -123,15 +133,15 @@ public class Cache {
|
||||
}
|
||||
|
||||
public <V> TypedCache<V> typed(Function<Object, V> read, Function<V, Object> write) {
|
||||
return new TypedCache<V>(cache, read, write);
|
||||
return new TypedCache<V>(cache, cacheType, read, write);
|
||||
}
|
||||
|
||||
public <V> TypedCache<V> cast(Class<V> cls) {
|
||||
return new TypedCache<V>(cache, it -> cls.cast(it), it -> it);
|
||||
return new TypedCache<V>(cache, cacheType, it -> cls.cast(it), it -> it);
|
||||
}
|
||||
|
||||
public <V> TypedCache<List<V>> castList(Class<V> cls) {
|
||||
return new TypedCache<List<V>>(cache, it -> it == null ? null : stream((Object[]) it).map(cls::cast).collect(toList()), it -> it == null ? null : it.toArray());
|
||||
return new TypedCache<List<V>>(cache, cacheType, it -> it == null ? null : stream((Object[]) it).map(cls::cast).collect(toList()), it -> it == null ? null : it.toArray());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -140,8 +150,8 @@ public class Cache {
|
||||
private final Function<Object, V> read;
|
||||
private final Function<V, Object> write;
|
||||
|
||||
public TypedCache(net.sf.ehcache.Cache cache, Function<Object, V> read, Function<V, Object> write) {
|
||||
super(cache);
|
||||
public TypedCache(net.sf.ehcache.Cache cache, CacheType cacheType, Function<Object, V> read, Function<V, Object> write) {
|
||||
super(cache, cacheType);
|
||||
this.read = read;
|
||||
this.write = write;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class CacheManager {
|
||||
if (!manager.cacheExists(name)) {
|
||||
manager.addCache(new net.sf.ehcache.Cache(type.getConfiguration(name)));
|
||||
}
|
||||
return new Cache(manager.getCache(name));
|
||||
return new Cache(manager.getCache(name), type);
|
||||
}
|
||||
|
||||
public synchronized void clearAll() {
|
||||
|
@ -15,6 +15,7 @@ import java.util.concurrent.Callable;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
@ -189,21 +190,41 @@ public class CachedResource<K, R> implements Resource<R> {
|
||||
};
|
||||
}
|
||||
|
||||
public static Fetch fetchIfNoneMatch(Transform<URL, ?> key, Cache cache) {
|
||||
// create cache with the same config
|
||||
Cache etagStorage = Cache.getCache(cache.getName() + "_etag", cache.getCacheType());
|
||||
|
||||
// make sure value cache contains key, otherwise ignore previously stored etag
|
||||
return fetchIfNoneMatch(url -> {
|
||||
try {
|
||||
return cache.get(key.transform(url)) == null ? null : etagStorage.get(key.transform(url));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, (url, etag) -> {
|
||||
try {
|
||||
etagStorage.put(key.transform(url), etag);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Fetch fetchIfNoneMatch(Function<URL, Object> etagRetrieve, BiConsumer<URL, String> etagStore) {
|
||||
return (url, lastModified) -> {
|
||||
Object etagValue = etagRetrieve.apply(url);
|
||||
debug.fine(WebRequest.log(url, lastModified, etagValue));
|
||||
try {
|
||||
return WebRequest.fetch(url, etagValue == null ? lastModified : 0, etagValue, null, storeETag(url, etagStore));
|
||||
return WebRequest.fetch(url, etagValue == null ? lastModified : 0, etagValue, null, storeETag(url, etagStore, etag -> !etag.equals(etagValue)));
|
||||
} catch (FileNotFoundException e) {
|
||||
return fileNotFound(url, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Consumer<Map<String, List<String>>> storeETag(URL url, BiConsumer<URL, String> etagStore) {
|
||||
private static Consumer<Map<String, List<String>>> storeETag(URL url, BiConsumer<URL, String> etagStore, Predicate<String> etagFilter) {
|
||||
return (responseHeaders) -> {
|
||||
WebRequest.getETag(responseHeaders).ifPresent(etag -> {
|
||||
WebRequest.getETag(responseHeaders).filter(etagFilter).ifPresent(etag -> {
|
||||
debug.finest(format("Store ETag: %s", etag));
|
||||
etagStore.accept(url, etag);
|
||||
});
|
||||
|
@ -33,7 +33,6 @@ import javax.swing.Icon;
|
||||
|
||||
import net.filebot.Cache;
|
||||
import net.filebot.CacheType;
|
||||
import net.filebot.CachedResource.Fetch;
|
||||
import net.filebot.Language;
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.web.TMDbClient.MovieInfo.MovieProperty;
|
||||
@ -297,11 +296,8 @@ public class TMDbClient implements MovieIdentificationService, ArtworkProvider {
|
||||
String key = parameters.isEmpty() ? resource : resource + '?' + encodeParameters(parameters, true);
|
||||
String cacheName = locale.getLanguage().isEmpty() ? getName() : getName() + "_" + locale;
|
||||
|
||||
Cache etagStorage = Cache.getCache(cacheName + "_etag", CacheType.Monthly);
|
||||
Cache cache = Cache.getCache(cacheName, CacheType.Monthly);
|
||||
|
||||
Fetch fetchIfNoneMatch = fetchIfNoneMatch(url -> cache.get(key) == null ? null : etagStorage.get(key), (url, etag) -> etagStorage.put(key, etag));
|
||||
Object json = cache.json(key, s -> getResource(s, locale)).fetch(withPermit(fetchIfNoneMatch, r -> limit.acquirePermit())).expire(Cache.ONE_WEEK).get();
|
||||
Object json = cache.json(key, k -> getResource(k, locale)).fetch(withPermit(fetchIfNoneMatch(url -> key, cache), r -> limit.acquirePermit())).expire(Cache.ONE_WEEK).get();
|
||||
|
||||
if (asMap(json).isEmpty()) {
|
||||
throw new FileNotFoundException(String.format("Resource is empty: %s => %s", json, getResource(key, locale)));
|
||||
|
Loading…
Reference in New Issue
Block a user