* make sure shared resources are only fetched once in multi-threaded scenarios

This commit is contained in:
Reinhard Pointner 2012-01-03 09:18:32 +00:00
parent 4341922677
commit 4d45826540
3 changed files with 54 additions and 51 deletions

View File

@ -49,6 +49,9 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
private final EpisodeListProvider provider;
// only allow one fetch session at a time so later requests can make use of cached results
private final Object providerLock = new Object();
public EpisodeListMatcher(EpisodeListProvider provider) {
this.provider = provider;
@ -222,7 +225,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
Collection<String> names = detectSeriesNames(files, locale);
if (names.size() > 0) {
// only allow one fetch session at a time so later requests can make use of cached results
synchronized (provider) {
synchronized (providerLock) {
episodes = fetchEpisodeSet(names, locale, parent);
}
}
@ -246,7 +249,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
if (input.size() > 0) {
// only allow one fetch session at a time so later requests can make use of cached results
synchronized (provider) {
synchronized (providerLock) {
episodes = fetchEpisodeSet(input, locale, parent);
}
}

View File

@ -14,9 +14,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
@ -37,50 +37,50 @@ public class AnidbClient extends AbstractEpisodeListProvider {
private final String client;
private final int clientver;
public AnidbClient(String client, int clientver) {
this.client = client;
this.clientver = clientver;
}
@Override
public String getName() {
return "AniDB";
}
@Override
public Icon getIcon() {
return ResourceManager.getIcon("search.anidb");
}
@Override
public boolean hasSingleSeasonSupport() {
return false;
}
@Override
public boolean hasLocaleSupport() {
return true;
}
@Override
public ResultCache getCache() {
return new ResultCache(host, CacheManager.getInstance().getCache("web-persistent-datasource"));
}
@Override
public List<SearchResult> search(String query, final Locale locale) throws Exception {
// bypass automatic caching since search is based on locally cached data anyway
return fetchSearchResult(query, locale);
}
@Override
public List<SearchResult> fetchSearchResult(String query, final Locale locale) throws Exception {
LocalSearch<AnidbSearchResult> index = new LocalSearch<AnidbSearchResult>(getAnimeTitles()) {
@ -94,7 +94,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
return new ArrayList<SearchResult>(index.search(query));
}
@Override
public List<Episode> fetchEpisodeList(SearchResult searchResult, Locale language) throws Exception {
AnidbSearchResult anime = (AnidbSearchResult) searchResult;
@ -142,7 +142,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
return episodes;
}
@Override
public URI getEpisodeListLink(SearchResult searchResult) {
int aid = ((AnidbSearchResult) searchResult).getAnimeId();
@ -154,24 +154,24 @@ public class AnidbClient extends AbstractEpisodeListProvider {
}
}
@Override
public List<Episode> getEpisodeList(SearchResult searchResult, int season, Locale locale) throws Exception {
throw new UnsupportedOperationException();
}
@Override
public URI getEpisodeListLink(SearchResult searchResult, int season) {
return null;
}
@SuppressWarnings("unchecked")
protected List<AnidbSearchResult> getAnimeTitles() throws Exception {
protected synchronized List<AnidbSearchResult> getAnimeTitles() throws Exception {
URL url = new URL("http", host, "/api/animetitles.dat.gz");
ResultCache cache = getCache();
@SuppressWarnings("unchecked")
List<AnidbSearchResult> anime = (List) cache.getSearchResult(null, Locale.ROOT);
if (anime != null) {
return anime;
@ -225,7 +225,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
return cache.putSearchResult(null, Locale.ROOT, anime);
}
public static class AnidbSearchResult extends SearchResult {
protected int aid;
@ -237,41 +237,41 @@ public class AnidbClient extends AbstractEpisodeListProvider {
// used by serializer
}
public AnidbSearchResult(int aid, String primaryTitle, Map<String, String> officialTitle) {
this.aid = aid;
this.primaryTitle = primaryTitle;
this.officialTitle = officialTitle;
}
public int getAnimeId() {
return aid;
}
@Override
public String getName() {
return primaryTitle;
}
public String getPrimaryTitle() {
return primaryTitle;
}
public String getOfficialTitle(String key) {
return officialTitle != null ? officialTitle.get(key) : null;
}
@Override
public int hashCode() {
return aid;
}
@Override
public boolean equals(Object object) {
if (object instanceof AnidbSearchResult) {

View File

@ -31,43 +31,43 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
private final String apikey;
public SerienjunkiesClient(String apikey) {
this.apikey = apikey;
}
@Override
public String getName() {
return "Serienjunkies";
}
@Override
public Icon getIcon() {
return ResourceManager.getIcon("search.serienjunkies");
}
@Override
public Locale getDefaultLocale() {
return Locale.GERMAN;
}
@Override
public ResultCache getCache() {
return new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
}
@Override
public List<SearchResult> search(String query, final Locale locale) throws Exception {
// bypass automatic caching since search is based on locally cached data anyway
return fetchSearchResult(query, locale);
}
@Override
public List<SearchResult> fetchSearchResult(String query, Locale locale) throws Exception {
LocalSearch<SerienjunkiesSearchResult> index = new LocalSearch<SerienjunkiesSearchResult>(getSeriesTitles()) {
@ -81,8 +81,8 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
return new ArrayList<SearchResult>(index.search(query));
}
protected List<SerienjunkiesSearchResult> getSeriesTitles() throws IOException {
protected synchronized List<SerienjunkiesSearchResult> getSeriesTitles() throws IOException {
ResultCache cache = getCache();
@SuppressWarnings("unchecked")
@ -113,7 +113,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
return cache.putSearchResult(null, Locale.ROOT, seriesList);
}
@Override
public List<Episode> fetchEpisodeList(SearchResult searchResult, Locale locale) throws IOException {
SerienjunkiesSearchResult series = (SerienjunkiesSearchResult) searchResult;
@ -142,7 +142,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
return episodes;
}
protected Object request(String resource) throws IOException {
URL url = new URL("https", host, resource);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
@ -159,24 +159,24 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
}
}
@Override
public URI getEpisodeListLink(SearchResult searchResult) {
return getEpisodeListLink(searchResult, "alle-serien-staffeln");
}
@Override
public URI getEpisodeListLink(SearchResult searchResult, int season) {
return getEpisodeListLink(searchResult, "season" + season);
}
public URI getEpisodeListLink(SearchResult searchResult, String page) {
return URI.create(String.format("http://www.serienjunkies.de/%s/%s.html", ((SerienjunkiesSearchResult) searchResult).getLink(), page));
}
public static class SerienjunkiesSearchResult extends SearchResult {
protected int sid;
@ -185,12 +185,12 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
protected String germanTitle;
protected Date startDate;
protected SerienjunkiesSearchResult() {
// used by serializer
}
public SerienjunkiesSearchResult(int sid, String link, String mainTitle, String germanTitle, Date startDate) {
this.sid = sid;
this.link = link;
@ -199,44 +199,44 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
this.startDate = startDate;
}
@Override
public String getName() {
return germanTitle != null ? germanTitle : mainTitle; // prefer German title
}
public int getSeriesId() {
return sid;
}
public String getLink() {
return link;
}
public String getMainTitle() {
return mainTitle;
}
public String getGermanTitle() {
return germanTitle;
}
public Date getStartDate() {
return startDate;
}
@Override
public int hashCode() {
return sid;
}
@Override
public boolean equals(Object object) {
if (object instanceof SerienjunkiesSearchResult) {