diff options
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; } @@ -1084,12 +1085,49 @@ public class RepositoryManager implements IRepositoryManager { } /** + * 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;
- }
}
|