mirror of
https://github.com/apache/archiva.git
synced 2025-02-23 02:56:38 +00:00
Stabilised file lock implementation and tests
This commit is contained in:
parent
60080379a6
commit
8dc5e696d2
@ -31,6 +31,7 @@
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* @author Olivier Lamy
|
||||
@ -51,7 +52,6 @@ public class DefaultFileLockManager
|
||||
|
||||
private int timeout = 0;
|
||||
|
||||
|
||||
@Override
|
||||
public Lock readFileLock( File file )
|
||||
throws FileLockException, FileLockTimeoutException
|
||||
@ -162,20 +162,18 @@ public Lock writeFileLock( File file )
|
||||
}
|
||||
}
|
||||
|
||||
Lock current = lockFiles.get( file );
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Lock current = lockFiles.get( file );
|
||||
if ( current != null )
|
||||
{
|
||||
log.debug( "write lock file exist continue wait" );
|
||||
|
||||
continue;
|
||||
}
|
||||
lock = new Lock( file, true );
|
||||
createNewFileQuietly( file );
|
||||
lock.openLock( true, timeout > 0 );
|
||||
lock = new Lock(file, true);
|
||||
createNewFileQuietly(file);
|
||||
lock.openLock(true, timeout > 0);
|
||||
acquired = true;
|
||||
}
|
||||
catch ( FileNotFoundException e )
|
||||
@ -191,12 +189,29 @@ public Lock writeFileLock( File file )
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
if (lock!=null && lock.isValid()) {
|
||||
try {
|
||||
lock.close();
|
||||
} catch (IOException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
throw new FileLockException( e.getMessage(), e );
|
||||
}
|
||||
catch ( IllegalStateException e )
|
||||
catch ( Throwable e )
|
||||
{
|
||||
if (lock!=null && lock.isValid()) {
|
||||
try {
|
||||
lock.close();
|
||||
} catch (IOException ex) {
|
||||
// Ignore
|
||||
} finally {
|
||||
lock = null;
|
||||
}
|
||||
}
|
||||
log.debug( "openLock {}:{}", e.getClass(), e.getMessage() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Lock current = lockFiles.putIfAbsent( file, lock );
|
||||
|
@ -90,7 +90,7 @@ public boolean isShared()
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return this.fileLock.isValid();
|
||||
return this.fileLock!=null && this.fileLock.isValid();
|
||||
}
|
||||
|
||||
public Map<Thread, AtomicInteger> getFileClients()
|
||||
|
@ -35,7 +35,9 @@
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -83,6 +85,22 @@ public void initialize()
|
||||
|
||||
}
|
||||
|
||||
// Files.copy is not atomic so have to try several times in
|
||||
// a multithreaded test
|
||||
private void copyFile(Path source, Path destination) {
|
||||
int attempts=10;
|
||||
boolean finished = false;
|
||||
while(!finished && attempts-->0) {
|
||||
try {
|
||||
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES);
|
||||
finished=true;
|
||||
} catch (IOException ex) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void thread1()
|
||||
throws FileLockException, FileLockTimeoutException, IOException
|
||||
{
|
||||
@ -91,8 +109,7 @@ public void thread1()
|
||||
try
|
||||
{
|
||||
lock.getFile().delete();
|
||||
Files.copy( largeJar.toPath(), lock.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES );
|
||||
copyFile( largeJar.toPath(), lock.getFile().toPath());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -110,8 +127,7 @@ public void thread2()
|
||||
try
|
||||
{
|
||||
lock.getFile().delete();
|
||||
Files.copy( largeJar.toPath(), lock.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES );
|
||||
copyFile( largeJar.toPath(), lock.getFile().toPath());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -147,8 +163,7 @@ public void thread4()
|
||||
try
|
||||
{
|
||||
lock.getFile().delete();
|
||||
Files.copy( largeJar.toPath(), lock.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES );
|
||||
copyFile( largeJar.toPath(), lock.getFile().toPath());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -166,8 +181,7 @@ public void thread5()
|
||||
try
|
||||
{
|
||||
lock.getFile().delete();
|
||||
Files.copy( largeJar.toPath(), lock.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES );
|
||||
copyFile( largeJar.toPath(), lock.getFile().toPath());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -202,8 +216,7 @@ public void thread7()
|
||||
try
|
||||
{
|
||||
lock.getFile().delete();
|
||||
Files.copy( largeJar.toPath(), lock.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES );
|
||||
copyFile( largeJar.toPath(), lock.getFile().toPath());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -238,8 +251,7 @@ public void thread9()
|
||||
try
|
||||
{
|
||||
lock.getFile().delete();
|
||||
Files.copy( largeJar.toPath(), lock.getFile().toPath(), StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES );
|
||||
copyFile( largeJar.toPath(), lock.getFile().toPath());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -283,9 +295,9 @@ public void testWrite()
|
||||
{
|
||||
ConcurrentFileWrite concurrentFileWrite = new ConcurrentFileWrite( fileLockManager );
|
||||
//concurrentFileWrite.setTrace( true );
|
||||
TestFramework.runOnce( concurrentFileWrite );
|
||||
TestFramework.runManyTimes( concurrentFileWrite, 10);
|
||||
logger.info( "success: {}", concurrentFileWrite.success );
|
||||
Assert.assertEquals( 10, concurrentFileWrite.success.intValue() );
|
||||
Assert.assertEquals( 100, concurrentFileWrite.success.intValue() );
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user