From b72fc2b4942d45f4e8317821be0c3eb470b1688f Mon Sep 17 00:00:00 2001 From: Saša Živkov Date: Tue, 22 Mar 2016 17:23:53 +0100 Subject: Make the FileLfsRepository thread safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FileLfsRepository.out member could have been accessed from multiple threads which would corrupt the content. Don't store the AtomicObjectOutputStream in the FileLfsRepository.out but move it to the ObjectUploadListener which is instantiated per-request. Add a parallel upload test. Change-Id: I62298630e99c46b500d376843ffcde934436215b Signed-off-by: Saša Živkov Signed-off-by: Matthias Sohn --- .../org/eclipse/jgit/lfs/server/fs/UploadTest.java | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'org.eclipse.jgit.lfs.server.test') diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java index 35bf09b0c1..1fb91bd29d 100644 --- a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java @@ -51,6 +51,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; import org.eclipse.jgit.lfs.lib.LongObjectId; @@ -98,4 +105,36 @@ public class UploadTest extends LfsServerTest { assertEquals("expected object length " + Files.size(f), Files.size(f), repository.getSize(id)); } + + @Test + public void testParallelUploads() throws Exception { + int count = 10; + List paths = new ArrayList<>(count); + + for (int i = 0; i < count; i++) { + Path f = Paths.get(getTempDirectory().toString(), + "largeRandomFile_" + i); + createPseudoRandomContentFile(f, 1 * MiB); + paths.add(f); + } + + final CyclicBarrier barrier = new CyclicBarrier(count); + + ExecutorService e = Executors.newFixedThreadPool(count); + try { + for (final Path p : paths) { + e.submit(new Callable() { + @Override + public Void call() throws Exception { + barrier.await(); + putContent(p); + return null; + } + }); + } + } finally { + e.shutdown(); + e.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + } + } } -- cgit v1.2.3