From 5e36f65e0e29456c422c90854e1babef8a679980 Mon Sep 17 00:00:00 2001 From: gtully Date: Fri, 15 May 2015 13:23:12 +0100 Subject: [PATCH] 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 --- .../org/apache/activemq/util/LockFile.java | 18 +++++++++--------- .../store/kahadb/KahaDBDeleteLockTest.java | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/activemq-broker/src/main/java/org/apache/activemq/util/LockFile.java b/activemq-broker/src/main/java/org/apache/activemq/util/LockFile.java index 45e26caaa1..516c5c25dc 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/util/LockFile.java +++ b/activemq-broker/src/main/java/org/apache/activemq/util/LockFile.java @@ -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; } } diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBDeleteLockTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBDeleteLockTest.java index 53de60335b..390072e95d 100644 --- a/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBDeleteLockTest.java +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/store/kahadb/KahaDBDeleteLockTest.java @@ -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);