https://issues.apache.org/jira/browse/AMQ-4705 - lastmod granualarity is second on some nix. Also write on lock acquire to ensure modification time change

This commit is contained in:
gtully 2015-05-15 13:23:12 +01:00
parent 4c8a4722a1
commit 5e36f65e0e
2 changed files with 22 additions and 11 deletions

View File

@ -24,7 +24,6 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.Calendar;
import java.util.Date;
/**
@ -39,7 +38,7 @@ public class LockFile {
private long lastModified;
private FileLock lock;
private RandomAccessFile readFile;
private RandomAccessFile randomAccessLockFile;
private int lockCounter;
private final boolean deleteOnUnlock;
private volatile boolean locked;
@ -72,18 +71,19 @@ public class LockFile {
}
try {
if (lock == null) {
readFile = new RandomAccessFile(file, "rw");
randomAccessLockFile = new RandomAccessFile(file, "rw");
IOException reason = null;
try {
lock = readFile.getChannel().tryLock(0, Math.max(1, readFile.getChannel().size()), false);
lock = randomAccessLockFile.getChannel().tryLock(0, Math.max(1, randomAccessLockFile.getChannel().size()), false);
} catch (OverlappingFileLockException e) {
reason = IOExceptionSupport.create("File '" + file + "' could not be locked.", e);
} catch (IOException ioe) {
reason = ioe;
}
if (lock != null) {
//Set lastModified only if we are able to successfully obtain the lock.
readFile.getChannel().force(true);
//track lastModified only if we are able to successfully obtain the lock.
randomAccessLockFile.writeLong(System.currentTimeMillis());
randomAccessLockFile.getChannel().force(true);
lastModified = file.lastModified();
lockCounter++;
System.setProperty(getVmLockKey(), new Date().toString());
@ -141,12 +141,12 @@ public class LockFile {
private void closeReadFile() {
// close the file.
if (readFile != null) {
if (randomAccessLockFile != null) {
try {
readFile.close();
randomAccessLockFile.close();
} catch (Throwable ignore) {
}
readFile = null;
randomAccessLockFile = null;
}
}

View File

@ -21,15 +21,19 @@ import org.apache.activemq.util.Wait;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertTrue;
public class KahaDBDeleteLockTest {
static final Logger LOG = LoggerFactory.getLogger(KahaDBDeleteLockTest.class);
protected BrokerService master;
@ -48,6 +52,12 @@ public class KahaDBDeleteLockTest {
masterPersistenceAdapter.setDirectory(kahaDataDir);
masterPersistenceAdapter.setLockKeepAlivePeriod(500);
// ensure broker creates the file
File lockFile = new File(kahaDataDir, "lock");
if (lockFile.exists()) {
lockFile.delete();
}
master.setPersistenceAdapter(masterPersistenceAdapter);
master.start();
master.waitUntilStarted();
@ -97,12 +107,13 @@ public class KahaDBDeleteLockTest {
assertTrue("lock file exists via modification time", Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
LOG.info("Lock file " + lockFile.getAbsolutePath() + ", last mod at: " + new Date(lockFile.lastModified()));
return lockFile.lastModified() > 0;
}
}));
// ensure modification will be seen, milisecond granularity
TimeUnit.MILLISECONDS.sleep(10);
// ensure modification will be seen, second granularity on some nix
TimeUnit.SECONDS.sleep(2);
RandomAccessFile file = new RandomAccessFile(lockFile, "rw");
file.write(4);
file.getChannel().force(true);