diff options
author | Olivier Lamy <olamy@apache.org> | 2013-12-13 04:47:36 +0000 |
---|---|---|
committer | Olivier Lamy <olamy@apache.org> | 2013-12-13 04:47:36 +0000 |
commit | e1c3663b01097bae32e923304e218dadca043729 (patch) | |
tree | 0659a4ecb0efa8f038a70ef3fcc925cb76f312f6 /archiva-modules/archiva-base/archiva-filelock | |
parent | a9036273239ad7c015c56a7439ddf3cdad4cb45e (diff) | |
download | archiva-e1c3663b01097bae32e923304e218dadca043729.tar.gz archiva-e1c3663b01097bae32e923304e218dadca043729.zip |
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
Diffstat (limited to 'archiva-modules/archiva-base/archiva-filelock')
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 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> + <!-- jvm holds lock on file so use a new one per test --> + <reuseForks>false</reuseForks> <systemPropertyVariables> <buildDirectory>${project.build.directory}</buildDirectory> <java.io.tmpdir>${project.build.directory}</java.io.tmpdir> 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<File, Lock> lockFiles = new ConcurrentHashMap<File, Lock>( 64 ); + private static final ConcurrentMap<File, Lock> lockFiles = new ConcurrentHashMap<File, Lock>( 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() ); |