mirror of https://github.com/apache/archiva.git
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
This commit is contained in:
parent
a903627323
commit
e1c3663b01
|
@ -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>
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -51,6 +51,8 @@ public interface FileLockManager
|
|||
void release( Lock lock )
|
||||
throws FileLockException, FileNotFoundException;
|
||||
|
||||
void clearLockFiles();
|
||||
|
||||
int getTimeout();
|
||||
|
||||
void setTimeout( int timeout );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() );
|
||||
|
|
Loading…
Reference in New Issue