From fa2a3efcc7bfd8e15a04d95c8cc05c92fc59066f Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Wed, 2 Apr 2014 03:55:28 +0000 Subject: [MRM-1802] Find a cache solution for browsing part (especially root browsing) git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1583867 13f79535-47bb-0310-9956-ffa450edef68 --- .../repository/DefaultMetadataResolver.java | 65 +++++++++++++++++----- .../src/main/resources/META-INF/spring-context.xml | 11 ++++ 2 files changed, 62 insertions(+), 14 deletions(-) (limited to 'archiva-modules/metadata') diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java index 469b4cf46..5c921d68b 100644 --- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java +++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/DefaultMetadataResolver.java @@ -29,6 +29,7 @@ import org.apache.archiva.metadata.repository.storage.RepositoryStorage; import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException; import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException; import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; +import org.apache.archiva.redback.components.cache.Cache; import org.apache.archiva.repository.events.RepositoryListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,21 +44,21 @@ import java.util.List; /** * Default implementation of the metadata resolver API. At present it will handle updating the content repository * from new or changed information in the model and artifacts from the repository storage. - *

+ *

* This is a singleton component to allow an alternate implementation to be provided. It is intended to be the same * system-wide for the whole content repository instead of on a per-managed-repository basis. Therefore, the session is * passed in as an argument to obtain any necessary resources, rather than the class being instantiated within the * session in the context of a single managed repository's resolution needs. - *

+ *

* Note that the caller is responsible for the session, such as closing and saving (which is implied by the resolver * being obtained from within the session). The {@link RepositorySession#markDirty()} method is used as a hint to ensure * that the session knows we've made changes at close. We cannot ensure the changes will be persisted if the caller * chooses to revert first. This is preferable to storing the metadata immediately - a separate session would require * having a bi-directional link with the session factory, and saving the existing session might save other changes * unknowingly by the caller. - *

+ *

*/ -@Service ("metadataResolver#default") +@Service("metadataResolver#default") public class DefaultMetadataResolver implements MetadataResolver { @@ -67,20 +68,24 @@ public class DefaultMetadataResolver /** * FIXME: this needs to be configurable based on storage type - and could also be instantiated per repo. Change to a * factory, and perhaps retrieve from the session. We should avoid creating one per request, however. - *

+ *

* TODO: Also need to accommodate availability of proxy module * ... could be a different type since we need methods to modify the storage metadata, which would also allow more * appropriate methods to pass in the already determined repository configuration, for example, instead of the ID */ @Inject - @Named (value = "repositoryStorage#maven2") + @Named(value = "repositoryStorage#maven2") private RepositoryStorage repositoryStorage; + @Inject + private List listeners; + /** - * + * Cache used for namespaces */ @Inject - private List listeners; + @Named( value = "cache#namespaces" ) + private Cache> namespacesCache; public ProjectVersionMetadata resolveProjectVersion( RepositorySession session, String repoId, String namespace, String projectId, String projectVersion ) @@ -176,8 +181,15 @@ public class DefaultMetadataResolver { try { + + Collection namespaces = namespacesCache.get( repoId ); + if ( namespaces != null ) + { + return namespaces; + } + MetadataRepository metadataRepository = session.getRepository(); - Collection namespaces = metadataRepository.getRootNamespaces( repoId ); + namespaces = metadataRepository.getRootNamespaces( repoId ); Collection storageNamespaces = repositoryStorage.listRootNamespaces( repoId, new ExcludesFilter( namespaces ) ); if ( storageNamespaces != null && !storageNamespaces.isEmpty() ) @@ -190,6 +202,9 @@ public class DefaultMetadataResolver try { metadataRepository.updateNamespace( repoId, n ); + // just invalidate cache entry + String cacheKey = repoId + "-" + n; + namespacesCache.remove( cacheKey ); } catch ( MetadataRepositoryException e ) { @@ -201,6 +216,9 @@ public class DefaultMetadataResolver namespaces = new ArrayList( namespaces ); namespaces.addAll( storageNamespaces ); } + + namespacesCache.put( repoId, namespaces ); + return namespaces; } catch ( RepositoryStorageRuntimeException e ) @@ -215,7 +233,13 @@ public class DefaultMetadataResolver try { MetadataRepository metadataRepository = session.getRepository(); - Collection namespaces = metadataRepository.getNamespaces( repoId, namespace ); + String cacheKey = repoId + "-" + namespace; + Collection namespaces = namespacesCache.get( cacheKey ); + if ( namespaces == null ) + { + namespaces = metadataRepository.getNamespaces( repoId, namespace ); + namespacesCache.put( cacheKey, namespaces ); + } Collection exclusions = new ArrayList( namespaces ); exclusions.addAll( metadataRepository.getProjects( repoId, namespace ) ); Collection storageNamespaces = @@ -230,6 +254,9 @@ public class DefaultMetadataResolver try { metadataRepository.updateNamespace( repoId, namespace + "." + n ); + // just invalidate cache entry + cacheKey = repoId + "-" + namespace + "." + n; + namespacesCache.remove( cacheKey ); } catch ( MetadataRepositoryException e ) { @@ -257,7 +284,17 @@ public class DefaultMetadataResolver MetadataRepository metadataRepository = session.getRepository(); Collection projects = metadataRepository.getProjects( repoId, namespace ); Collection exclusions = new ArrayList( projects ); - exclusions.addAll( metadataRepository.getNamespaces( repoId, namespace ) ); + + String cacheKey = repoId + "-" + namespace; + Collection namespaces = namespacesCache.get( cacheKey ); + if ( namespaces == null ) + { + namespaces = metadataRepository.getNamespaces( repoId, namespace ); + namespacesCache.put( cacheKey, namespaces ); + } + + exclusions.addAll( namespaces ); + Collection storageProjects = repositoryStorage.listProjects( repoId, namespace, new ExcludesFilter( exclusions ) ); if ( storageProjects != null && !storageProjects.isEmpty() ) @@ -333,7 +370,7 @@ public class DefaultMetadataResolver { log.warn( "Not update project in metadata repository due to an error resolving it from storage: {}", - e.getMessage() ); + e.getMessage() ); for ( RepositoryListener listener : listeners ) { @@ -373,8 +410,8 @@ public class DefaultMetadataResolver ExcludesFilter filter = new ExcludesFilter( createArtifactIdList( artifacts ) ); ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( repoId ).namespace( namespace ).projectId( projectId ).projectVersion( - projectVersion ).filter( filter ); + new ReadMetadataRequest().repositoryId( repoId ).namespace( namespace ).projectId( + projectId ).projectVersion( projectVersion ).filter( filter ); Collection storageArtifacts = repositoryStorage.readArtifactsMetadata( readMetadataRequest ); diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml b/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml index e7c511811..34e5c3d5d 100644 --- a/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml +++ b/archiva-modules/metadata/metadata-repository-api/src/main/resources/META-INF/spring-context.xml @@ -39,4 +39,15 @@ + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3