浏览代码

Cancel gc if thread was interrupted

see
https://groups.google.com/d/msg/repo-discuss/oDB2rl3doDc/tFEh5Xt0CAAJ

Change-Id: Ia6d4631c64e065d8b9b09e0b45e7a9ea8ac3f41d
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
tags/v5.3.0.201903061415-rc1
Matthias Sohn 6 年前
父节点
当前提交
882fed0d96

+ 52
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java 查看文件

import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;


import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;


import org.eclipse.jgit.errors.CancelledException;
import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.pack.PackWriter; import org.eclipse.jgit.internal.storage.pack.PackWriter;
import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.EmptyProgressMonitor; import org.eclipse.jgit.lib.EmptyProgressMonitor;
import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.lib.Sets;
import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
import org.junit.Test; import org.junit.Test;


public class GcConcurrentTest extends GcTestCase { public class GcConcurrentTest extends GcTestCase {
assertEquals(getSinglePack(repository).getPackName(), newPackName); assertEquals(getSinglePack(repository).getPackName(), newPackName);
assertNotNull(getSinglePack(repository).getBitmapIndex()); assertNotNull(getSinglePack(repository).getBitmapIndex());
} }

@Test
public void testInterruptGc() throws Exception {
FileBasedConfig c = repo.getConfig();
c.setInt(ConfigConstants.CONFIG_GC_SECTION, null,
ConfigConstants.CONFIG_KEY_AUTOPACKLIMIT, 1);
c.save();
SampleDataRepositoryTestCase.copyCGitTestPacks(repo);
ExecutorService executor = Executors.newSingleThreadExecutor();
final CountDownLatch latch = new CountDownLatch(1);
Future<Collection<PackFile>> result = executor
.submit(new Callable<Collection<PackFile>>() {

@Override
public Collection<PackFile> call() throws Exception {
long start = System.currentTimeMillis();
System.out.println("starting gc");
latch.countDown();
Collection<PackFile> r = gc.gc();
System.out.println("gc took "
+ (System.currentTimeMillis() - start) + " ms");
return r;
}
});
try {
latch.await();
Thread.sleep(5);
executor.shutdownNow();
result.get();
fail("thread wasn't interrupted");
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof CancelledException) {
assertEquals(JGitText.get().operationCanceled,
cause.getMessage());
} else if (cause instanceof IOException) {
Throwable cause2 = cause.getCause();
assertTrue(cause2 instanceof InterruptedException
|| cause2 instanceof ExecutionException);
} else {
fail("unexpected exception " + e);
}
}
}
} }

+ 1
- 1
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java 查看文件

} }


private void checkCancelled() throws CancelledException { private void checkCancelled() throws CancelledException {
if (pm.isCancelled()) {
if (pm.isCancelled() || Thread.currentThread().isInterrupted()) {
throw new CancelledException(JGitText.get().operationCanceled); throw new CancelledException(JGitText.get().operationCanceled);
} }
} }

正在加载...
取消
保存