From e1c3663b01097bae32e923304e218dadca043729 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Fri, 13 Dec 2013 04:47:36 +0000 Subject: [PATCH] use a concurrent map to handle file lock git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1550641 13f79535-47bb-0310-9956-ffa450edef68 --- .../archiva-base/archiva-filelock/pom.xml | 2 + .../filelock/DefaultFileLockManager.java | 44 ++++++++++++++++++- .../common/filelock/FileLockManager.java | 2 + .../filelock/DefaultFileLockManagerTest.java | 15 +++++-- .../DefaultFileLockManagerTimeoutTest.java | 17 ++++--- 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/archiva-modules/archiva-base/archiva-filelock/pom.xml b/archiva-modules/archiva-base/archiva-filelock/pom.xml index f1d9bb7be..f03492abc 100644 --- a/archiva-modules/archiva-base/archiva-filelock/pom.xml +++ b/archiva-modules/archiva-base/archiva-filelock/pom.xml @@ -119,6 +119,8 @@ org.apache.maven.plugins maven-surefire-plugin + + false ${project.build.directory} ${project.build.directory} diff --git a/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java b/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java index 5c2048082..7bf62b992 100644 --- a/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java +++ b/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java @@ -41,7 +41,7 @@ public class DefaultFileLockManager // TODO currently we create lock for read and write!! // the idea could be to store lock here with various clients read/write // only read could be a more simple lock and acquire a write lock means waiting the end of all reading threads - //private static final ConcurrentMap lockFiles = new ConcurrentHashMap( 64 ); + private static final ConcurrentMap lockFiles = new ConcurrentHashMap( 64 ); private boolean skipLocking = false; @@ -64,12 +64,14 @@ public class DefaultFileLockManager mkdirs( file.getParentFile() ); try { + Lock lock = new Lock( file, false ); stopWatch.start(); while ( !acquired ) { + if ( timeout > 0 ) { long delta = stopWatch.getTime(); @@ -81,8 +83,18 @@ public class DefaultFileLockManager throw new FileLockTimeoutException(); } } + + Lock current = lockFiles.get( file ); + + if ( current != null ) + { + log.debug( "read lock file exist continue wait" ); + continue; + } + try { + file.createNewFile(); lock.openLock( false, timeout > 0 ); acquired = true; } @@ -95,9 +107,14 @@ public class DefaultFileLockManager log.debug( "openLock {}:{}", e.getClass(), e.getMessage() ); } } + Lock current = lockFiles.putIfAbsent( file, lock ); + if ( current != null ) + { + lock = current; + } return lock; } - catch ( FileNotFoundException e ) + catch ( IOException e ) { throw new FileLockException( e.getMessage(), e ); } @@ -137,8 +154,18 @@ public class DefaultFileLockManager throw new FileLockTimeoutException(); } } + + Lock current = lockFiles.get( file ); + + if ( current != null ) + { + log.debug( "write lock file exist continue wait" ); + continue; + } + try { + file.createNewFile(); lock.openLock( true, timeout > 0 ); acquired = true; } @@ -151,6 +178,13 @@ public class DefaultFileLockManager log.debug( "openLock {}:{}", e.getClass(), e.getMessage() ); } } + + Lock current = lockFiles.putIfAbsent( file, lock ); + if ( current != null ) + { + lock = current; + } + return lock; } catch ( FileNotFoundException e ) @@ -175,6 +209,7 @@ public class DefaultFileLockManager } try { + lockFiles.remove( lock.getFile() ); lock.close(); } catch ( IOException e ) @@ -183,6 +218,11 @@ public class DefaultFileLockManager } } + public void clearLockFiles() + { + lockFiles.clear(); + } + private boolean mkdirs( File directory ) { if ( directory == null ) diff --git a/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/FileLockManager.java b/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/FileLockManager.java index 4687d9002..80f6a5768 100644 --- a/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/FileLockManager.java +++ b/archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/FileLockManager.java @@ -51,6 +51,8 @@ public interface FileLockManager void release( Lock lock ) throws FileLockException, FileNotFoundException; + void clearLockFiles(); + int getTimeout(); void setTimeout( int timeout ); diff --git a/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java b/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java index 3f17725e7..40c47442f 100644 --- a/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java +++ b/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java @@ -24,6 +24,7 @@ import edu.umd.cs.mtc.TestFramework; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; @@ -42,15 +43,15 @@ import java.util.concurrent.atomic.AtomicInteger; /** * @author Olivier Lamy */ -@RunWith( SpringJUnit4ClassRunner.class ) -@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml" } ) +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath*:/META-INF/spring-context.xml" }) public class DefaultFileLockManagerTest { final Logger logger = LoggerFactory.getLogger( getClass() ); @Inject - @Named( value = "fileLockManager#default" ) + @Named(value = "fileLockManager#default") FileLockManager fileLockManager; class ConcurrentFileWrite @@ -263,6 +264,14 @@ public class DefaultFileLockManagerTest } + + @Before + public void initialize() + { + fileLockManager.setSkipLocking( false ); + fileLockManager.clearLockFiles(); + } + @Test public void testWrite() throws Throwable diff --git a/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTimeoutTest.java b/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTimeoutTest.java index 0b6fafa5b..acf7fe66e 100644 --- a/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTimeoutTest.java +++ b/archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTimeoutTest.java @@ -24,6 +24,7 @@ import edu.umd.cs.mtc.TestFramework; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; @@ -42,18 +43,26 @@ import java.util.concurrent.atomic.AtomicInteger; /** * @author Olivier Lamy */ -@RunWith( SpringJUnit4ClassRunner.class ) -@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml" } ) +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath*:/META-INF/spring-context.xml" }) public class DefaultFileLockManagerTimeoutTest { final Logger logger = LoggerFactory.getLogger( getClass() ); @Inject - @Named( value = "fileLockManager#default" ) + @Named(value = "fileLockManager#default") FileLockManager fileLockManager; + @Before + public void initialize() + { + fileLockManager.setSkipLocking( false ); + + fileLockManager.setTimeout( 5000 ); + fileLockManager.clearLockFiles(); + } @Test( expected = FileLockTimeoutException.class ) public void testTimeout() @@ -64,8 +73,6 @@ public class DefaultFileLockManagerTimeoutTest File largeJar = new File( System.getProperty( "basedir" ), "src/test/cassandra-all-2.0.3.jar" ); - fileLockManager.setTimeout( 5000 ); - Lock lock = fileLockManager.writeFileLock( file ); FileUtils.copyFile( largeJar, lock.getFile() ); -- 2.39.5