diff options
author | John Arthorne | 2008-02-29 21:56:22 +0000 |
---|---|---|
committer | John Arthorne | 2008-02-29 21:56:22 +0000 |
commit | f5a9ed5c50e642115b3e50b5cc8734e388d01286 (patch) | |
tree | 356961e7f61ddaeadeffab1ca8e14e6c45ff128c | |
parent | 51188a46cbb5dd4819fffaf38fd66d4b6c53dd08 (diff) | |
download | rt.equinox.p2-f5a9ed5c50e642115b3e50b5cc8734e388d01286.tar.gz rt.equinox.p2-f5a9ed5c50e642115b3e50b5cc8734e388d01286.tar.xz rt.equinox.p2-f5a9ed5c50e642115b3e50b5cc8734e388d01286.zip |
Bug 220872 Many (many) attempts to read from the same invalid artifact repositoryv200803040717
2 files changed, 91 insertions, 8 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/ArtifactRepositoryManager.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/ArtifactRepositoryManager.java index b04440cd9..22cf4ac56 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/ArtifactRepositoryManager.java +++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/ArtifactRepositoryManager.java @@ -60,6 +60,12 @@ public class ArtifactRepositoryManager implements IArtifactRepositoryManager { //lock object to be held when referring to the repositories field private final Object repositoryLock = new Object(); + /** + * Cache List of repositories that are not reachable. Maintain cache + * for short duration because repository may become available at any time. + */ + private SoftReference unavailableRepositories; + public ArtifactRepositoryManager() { //initialize repositories lazily } @@ -281,6 +287,8 @@ public class ArtifactRepositoryManager implements IArtifactRepositoryManager { IArtifactRepository result = getRepository(location); if (result != null) return result; + if (checkNotFound(location)) + fail(location, ProvisionException.REPOSITORY_NOT_FOUND); String[] suffixes = getAllSuffixes(); SubMonitor sub = SubMonitor.convert(monitor, suffixes.length * 100); for (int i = 0; i < suffixes.length; i++) { @@ -290,10 +298,42 @@ public class ArtifactRepositoryManager implements IArtifactRepositoryManager { return result; } } + rememberNotFound(location); fail(location, ProvisionException.REPOSITORY_NOT_FOUND); return null; } + /** + * Check if we recently attempted to load the given location and failed + * to find anything. Returns <code>true</code> if the repository was not + * found, and <code>false</code> otherwise. + */ + private boolean checkNotFound(URL location) { + if (unavailableRepositories == null) + return false; + List badRepos = (List) unavailableRepositories.get(); + if (badRepos == null) + return false; + return badRepos.contains(location); + } + + /** + * Cache the fact that we tried to load a repository at this location and did not find anything. + */ + private void rememberNotFound(URL location) { + List badRepos; + if (unavailableRepositories != null) { + badRepos = (List) unavailableRepositories.get(); + if (badRepos != null) { + badRepos.add(location); + return; + } + } + badRepos = new ArrayList(); + badRepos.add(location); + unavailableRepositories = new SoftReference(badRepos); + } + private IArtifactRepository loadRepository(URL location, String suffix, SubMonitor monitor) { IExtension[] providers = findMatchingRepositoryExtensions(suffix); // Loop over the candidates and return the first one that successfully loads diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/MetadataRepositoryManager.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/MetadataRepositoryManager.java index 691e9ac00..fb48d9501 100644 --- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/MetadataRepositoryManager.java +++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/MetadataRepositoryManager.java @@ -54,9 +54,16 @@ public class MetadataRepositoryManager implements IMetadataRepositoryManager { * obtained vai getKey(URL). */ private Map repositories = null; + //lock object to be held when referring to the repositories field private final Object repositoryLock = new Object(); + /** + * Cache List of repositories that are not reachable. Maintain cache + * for short duration because repository may become available at any time. + */ + private SoftReference unavailableRepositories; + public MetadataRepositoryManager() { //initialize repositories lazily } @@ -285,21 +292,57 @@ public class MetadataRepositoryManager implements IMetadataRepositoryManager { IMetadataRepository result = getRepository(location); if (result != null) return result; + MultiStatus notFoundStatus = new MultiStatus(Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, NLS.bind(Messages.repoMan_notExists, location.toExternalForm()), null); + if (checkNotFound(location)) + throw new ProvisionException(notFoundStatus); String[] suffixes = getAllSuffixes(); SubMonitor sub = SubMonitor.convert(monitor, Messages.REPOMGR_ADDING_REPO, suffixes.length * 100); - MultiStatus notFoundStatus = new MultiStatus(Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, NLS.bind(Messages.repoMan_notExists, location.toExternalForm()), null); - for (int i = 0; i < suffixes.length; i++) { - result = loadRepository(location, suffixes[i], sub.newChild(100), notFoundStatus); - if (result != null) { - addRepository(result); - sub.done(); - return result; + try { + for (int i = 0; i < suffixes.length; i++) { + result = loadRepository(location, suffixes[i], sub.newChild(100), notFoundStatus); + if (result != null) { + addRepository(result); + return result; + } } + } finally { + sub.done(); } - sub.done(); + rememberNotFound(location); throw new ProvisionException(notFoundStatus); } + /** + * Check if we recently attempted to load the given location and failed + * to find anything. Returns <code>true</code> if the repository was not + * found, and <code>false</code> otherwise. + */ + private boolean checkNotFound(URL location) { + if (unavailableRepositories == null) + return false; + List badRepos = (List) unavailableRepositories.get(); + if (badRepos == null) + return false; + return badRepos.contains(location); + } + + /** + * Cache the fact that we tried to load a repository at this location and did not find anything. + */ + private void rememberNotFound(URL location) { + List badRepos; + if (unavailableRepositories != null) { + badRepos = (List) unavailableRepositories.get(); + if (badRepos != null) { + badRepos.add(location); + return; + } + } + badRepos = new ArrayList(); + badRepos.add(location); + unavailableRepositories = new SoftReference(badRepos); + } + public IStatus validateRepositoryLocation(URL location, IProgressMonitor monitor) { Assert.isNotNull(location); IMetadataRepository result = getRepository(location); |