]> source.dussan.org Git - archiva.git/commitdiff
use a concurrent map to handle file lock
authorOlivier Lamy <olamy@apache.org>
Fri, 13 Dec 2013 04:47:36 +0000 (04:47 +0000)
committerOlivier Lamy <olamy@apache.org>
Fri, 13 Dec 2013 04:47:36 +0000 (04:47 +0000)
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1550641 13f79535-47bb-0310-9956-ffa450edef68

archiva-modules/archiva-base/archiva-filelock/pom.xml
archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/DefaultFileLockManager.java
archiva-modules/archiva-base/archiva-filelock/src/main/java/org/apache/archiva/common/filelock/FileLockManager.java
archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTest.java
archiva-modules/archiva-base/archiva-filelock/src/test/java/org/apache/archiva/common/filelock/DefaultFileLockManagerTimeoutTest.java

index f1d9bb7bef69724e44d594220e638564bc0a3beb..f03492abcac61684b5478e669d48743e7b6ad194 100644 (file)
         <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>
index 5c20480828cab8d891c0bd0162601f6bad930ad2..7bf62b992258f3dc270215ec2c8a0063272d41d3 100644 (file)
@@ -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 )
index 4687d9002425858ea43c2285d5de585ace270fa6..80f6a5768ac759ccc951b67427d50e973c125f74 100644 (file)
@@ -51,6 +51,8 @@ public interface FileLockManager
     void release( Lock lock )
         throws FileLockException, FileNotFoundException;
 
+    void clearLockFiles();
+
     int getTimeout();
 
     void setTimeout( int timeout );
index 3f17725e7c6f32d0213b3626e9a9679861e9146b..40c47442fd7a0188c6bcc6fe0dae1695fa4f1c0b 100644 (file)
@@ -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
index 0b6fafa5bde2403e088c9ec90477e6e7e1cb4c6c..acf7fe66e634db357fa9032e49a46ab1d706b338 100644 (file)
@@ -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() );