Introduce cache layer for workdirs

This commit is contained in:
René Pfeuffer
2020-04-13 12:22:13 +02:00
parent c92119f5eb
commit 5b034f8d02
21 changed files with 370 additions and 47 deletions

View File

@@ -30,10 +30,11 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.ScmTransportProtocol;
import sonia.scm.repository.GitUtil;
import sonia.scm.repository.GitWorkdirFactory;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.util.CacheSupportingWorkdirProvider;
import sonia.scm.repository.util.SimpleWorkdirFactory;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.util.SystemUtil;
import javax.inject.Inject;
@@ -46,7 +47,7 @@ import static sonia.scm.NotFoundException.notFound;
public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, Repository, GitContext> implements GitWorkdirFactory {
@Inject
public SimpleGitWorkdirFactory(WorkdirProvider workdirProvider) {
public SimpleGitWorkdirFactory(CacheSupportingWorkdirProvider workdirProvider) {
super(workdirProvider);
}
@@ -66,12 +67,17 @@ public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, Re
throw notFound(entity("Branch", initialBranch).in(context.getRepository()));
}
return new ParentAndClone<>(null, clone);
return new ParentAndClone<>(null, clone, target);
} catch (GitAPIException | IOException e) {
throw new InternalRepositoryException(context.getRepository(), "could not clone working copy of repository", e);
}
}
@Override
protected ParentAndClone<Repository, Repository> reclaimRepository(GitContext context, File target, String initialBranch) throws IOException {
return new ParentAndClone<>(null, GitUtil.open(target), target);
}
private String createScmTransportProtocolUri(File bareRepository) {
if (SystemUtil.isWindows()) {
return ScmTransportProtocol.NAME + ":///" + bareRepository.getAbsolutePath().replaceAll("\\\\", "/");

View File

@@ -44,6 +44,7 @@ import sonia.scm.repository.GitWorkdirFactory;
import sonia.scm.repository.Person;
import sonia.scm.repository.api.MergeCommandResult;
import sonia.scm.repository.api.MergeStrategy;
import sonia.scm.repository.util.NoneCachingWorkdirProvider;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.user.User;
@@ -424,7 +425,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
}
private GitMergeCommand createCommand(Consumer<Git> interceptor) {
return new GitMergeCommand(createContext(), new SimpleGitWorkdirFactory(new WorkdirProvider())) {
return new GitMergeCommand(createContext(), new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(new WorkdirProvider()))) {
@Override
<R, W extends GitCloneWorker<R>> R inClone(Function<Git, W> workerSupplier, GitWorkdirFactory workdirFactory, String initialBranch) {
Function<Git, W> interceptedWorkerSupplier = git -> {

View File

@@ -27,6 +27,7 @@ package sonia.scm.repository.spi;
import org.junit.Rule;
import org.junit.Test;
import sonia.scm.repository.spi.MergeConflictResult.SingleMergeConflict;
import sonia.scm.repository.util.NoneCachingWorkdirProvider;
import sonia.scm.repository.util.WorkdirProvider;
import java.io.IOException;
@@ -91,7 +92,7 @@ public class GitMergeCommand_Conflict_Test extends AbstractGitCommandTestBase {
}
private MergeConflictResult computeMergeConflictResult(String branchToMerge, String targetBranch) {
GitMergeCommand gitMergeCommand = new GitMergeCommand(createContext(), new SimpleGitWorkdirFactory(new WorkdirProvider()));
GitMergeCommand gitMergeCommand = new GitMergeCommand(createContext(), new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(new WorkdirProvider())));
MergeCommandRequest mergeCommandRequest = new MergeCommandRequest();
mergeCommandRequest.setBranchToMerge(branchToMerge);
mergeCommandRequest.setTargetBranch(targetBranch);

View File

@@ -42,6 +42,7 @@ import sonia.scm.BadRequestException;
import sonia.scm.ConcurrentModificationException;
import sonia.scm.NotFoundException;
import sonia.scm.repository.Person;
import sonia.scm.repository.util.NoneCachingWorkdirProvider;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
@@ -323,7 +324,7 @@ public class GitModifyCommandTest extends AbstractGitCommandTestBase {
}
private GitModifyCommand createCommand() {
return new GitModifyCommand(createContext(), new SimpleGitWorkdirFactory(new WorkdirProvider()), lfsBlobStoreFactory);
return new GitModifyCommand(createContext(), new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(new WorkdirProvider())), lfsBlobStoreFactory);
}
@FunctionalInterface

View File

@@ -35,6 +35,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import sonia.scm.repository.Person;
import sonia.scm.repository.util.NoneCachingWorkdirProvider;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.store.Blob;
import sonia.scm.store.BlobStore;
@@ -130,7 +131,7 @@ public class GitModifyCommand_LFSTest extends AbstractGitCommandTestBase {
}
private GitModifyCommand createCommand() {
return new GitModifyCommand(createContext(), new SimpleGitWorkdirFactory(new WorkdirProvider()), lfsBlobStoreFactory);
return new GitModifyCommand(createContext(), new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(new WorkdirProvider())), lfsBlobStoreFactory);
}
@Override

View File

@@ -38,6 +38,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import sonia.scm.repository.Person;
import sonia.scm.repository.util.NoneCachingWorkdirProvider;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.web.lfs.LfsBlobStoreFactory;
@@ -101,7 +102,7 @@ public class GitModifyCommand_withEmptyRepositoryTest extends AbstractGitCommand
}
private GitModifyCommand createCommand() {
return new GitModifyCommand(createContext(), new SimpleGitWorkdirFactory(new WorkdirProvider()), lfsBlobStoreFactory);
return new GitModifyCommand(createContext(), new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(new WorkdirProvider())), lfsBlobStoreFactory);
}
@FunctionalInterface

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.repository.spi;
import org.eclipse.jgit.lib.Repository;
@@ -35,6 +35,7 @@ import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.PreProcessorUtil;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.repository.util.NoneCachingWorkdirProvider;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.repository.util.WorkingCopy;
@@ -66,7 +67,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test
public void emptyPoolShouldCreateNewWorkdir() {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(workdirProvider));
File masterRepo = createRepositoryDirectory();
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
@@ -84,7 +85,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test
public void shouldCheckoutInitialBranch() {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(workdirProvider));
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), "test-branch")) {
assertThat(new File(workingCopy.getWorkingRepository().getWorkTree(), "a.txt"))
@@ -96,7 +97,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test
public void shouldCheckoutDefaultBranch() {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(workdirProvider));
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
assertThat(new File(workingCopy.getWorkingRepository().getWorkTree(), "a.txt"))
@@ -108,7 +109,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test
public void cloneFromPoolShouldNotBeReused() {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(workdirProvider));
File firstDirectory;
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
@@ -122,7 +123,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test
public void cloneFromPoolShouldBeDeletedOnClose() {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(new NoneCachingWorkdirProvider(workdirProvider));
File directory;
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {