From 388a233e8ec78c5d7279f9cef85245ea3c85534e Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 28 Feb 2014 14:04:37 -0500 Subject: [PATCH] Move GarbageCollector repository methods to the RepositoryManager --- .../com/gitblit/manager/GitblitManager.java | 15 ++++++ .../gitblit/manager/IRepositoryManager.java | 19 ++++++++ .../gitblit/manager/RepositoryManager.java | 46 +++++++++++++++++-- .../service/GarbageCollectorService.java | 23 +--------- 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 08d64085..6eb60236 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -1099,4 +1099,19 @@ public class GitblitManager implements IGitblit { public boolean deletePendingFederationProposal(FederationProposal proposal) { return federationManager.deletePendingFederationProposal(proposal); } + + @Override + public void closeAll() { + repositoryManager.closeAll(); + } + + @Override + public void close(String repository) { + repositoryManager.close(repository); + } + + @Override + public boolean isIdle(Repository repository) { + return repositoryManager.isIdle(repository); + } } diff --git a/src/main/java/com/gitblit/manager/IRepositoryManager.java b/src/main/java/com/gitblit/manager/IRepositoryManager.java index a4001915..23c61cb4 100644 --- a/src/main/java/com/gitblit/manager/IRepositoryManager.java +++ b/src/main/java/com/gitblit/manager/IRepositoryManager.java @@ -393,4 +393,23 @@ public interface IRepositoryManager extends IManager { */ boolean isCollectingGarbage(String repositoryName); + /** + * Ensures that all cached repositories are completely closed and their resources + * are properly released. + */ + void closeAll(); + + /** + * Ensures that a cached repository is completely closed and it's resources + * are properly released. + */ + void close(String repository); + + /** + * Returns true if the repository is idle (not being accessed). + * + * @param repository + * @return true if the repository is idle + */ + boolean isIdle(Repository repository); } \ No newline at end of file diff --git a/src/main/java/com/gitblit/manager/RepositoryManager.java b/src/main/java/com/gitblit/manager/RepositoryManager.java index 6b4fe97f..e412deba 100644 --- a/src/main/java/com/gitblit/manager/RepositoryManager.java +++ b/src/main/java/com/gitblit/manager/RepositoryManager.java @@ -169,6 +169,7 @@ public class RepositoryManager implements IRepositoryManager { gcExecutor.close(); mirrorExecutor.close(); + closeAll(); return this; } @@ -1083,13 +1084,50 @@ public class RepositoryManager implements IRepositoryManager { return size; } + /** + * Returns true if the repository is idle (not being accessed). + * + * @param repository + * @return true if the repository is idle + */ + @Override + public boolean isIdle(Repository repository) { + try { + // Read the use count. + // An idle use count is 2: + // +1 for being in the cache + // +1 for the repository parameter in this method + Field useCnt = Repository.class.getDeclaredField("useCnt"); + useCnt.setAccessible(true); + int useCount = ((AtomicInteger) useCnt.get(repository)).get(); + return useCount == 2; + } catch (Exception e) { + logger.warn(MessageFormat + .format("Failed to reflectively determine use count for repository {0}", + repository.getDirectory().getPath()), e); + } + return false; + } + + /** + * Ensures that all cached repository are completely closed and their resources + * are properly released. + */ + @Override + public void closeAll() { + for (String repository : getRepositoryList()) { + close(repository); + } + } + /** * Ensure that a cached repository is completely closed and its resources * are properly released. * * @param repositoryName */ - private void closeRepository(String repositoryName) { + @Override + public void close(String repositoryName) { Repository repository = getRepository(repositoryName); if (repository == null) { return; @@ -1114,7 +1152,7 @@ public class RepositoryManager implements IRepositoryManager { repositoryName), e); } if (uses > 0) { - logger.info(MessageFormat + logger.debug(MessageFormat .format("{0}.useCnt={1}, calling close() {2} time(s) to close object and ref databases", repositoryName, uses, uses)); for (int i = 0; i < uses; i++) { @@ -1252,7 +1290,7 @@ public class RepositoryManager implements IRepositoryManager { "Failed to rename ''{0}'' because ''{1}'' already exists.", repositoryName, repository.name)); } - closeRepository(repositoryName); + close(repositoryName); File folder = new File(repositoriesFolder, repositoryName); File destFolder = new File(repositoriesFolder, repository.name); if (destFolder.exists()) { @@ -1477,7 +1515,7 @@ public class RepositoryManager implements IRepositoryManager { @Override public boolean deleteRepository(String repositoryName) { try { - closeRepository(repositoryName); + close(repositoryName); // clear the repository cache clearRepositoryMetadataCache(repositoryName); diff --git a/src/main/java/com/gitblit/service/GarbageCollectorService.java b/src/main/java/com/gitblit/service/GarbageCollectorService.java index 8dbd8d83..b98560fd 100644 --- a/src/main/java/com/gitblit/service/GarbageCollectorService.java +++ b/src/main/java/com/gitblit/service/GarbageCollectorService.java @@ -15,7 +15,6 @@ */ package com.gitblit.service; -import java.lang.reflect.Field; import java.text.MessageFormat; import java.util.Calendar; import java.util.Date; @@ -23,7 +22,6 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jgit.api.GarbageCollectCommand; import org.eclipse.jgit.api.Git; @@ -33,7 +31,6 @@ import org.slf4j.LoggerFactory; import com.gitblit.IStoredSettings; import com.gitblit.Keys; -import com.gitblit.Keys.git; import com.gitblit.manager.IRepositoryManager; import com.gitblit.models.RepositoryModel; import com.gitblit.utils.FileUtils; @@ -160,7 +157,7 @@ public class GarbageCollectorService implements Runnable { continue; } - if (!isRepositoryIdle(repository)) { + if (!repositoryManager.isIdle(repository)) { logger.debug(MessageFormat.format("GCExecutor is skipping {0} because it is not idle", repositoryName)); continue; } @@ -228,22 +225,4 @@ public class GarbageCollectorService implements Runnable { running.set(false); } - - private boolean isRepositoryIdle(Repository repository) { - try { - // Read the use count. - // An idle use count is 2: - // +1 for being in the cache - // +1 for the repository parameter in this method - Field useCnt = Repository.class.getDeclaredField("useCnt"); - useCnt.setAccessible(true); - int useCount = ((AtomicInteger) useCnt.get(repository)).get(); - return useCount == 2; - } catch (Exception e) { - logger.warn(MessageFormat - .format("Failed to reflectively determine use count for repository {0}", - repository.getDirectory().getPath()), e); - } - return false; - } } -- 2.39.5