You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2019/08/05 13:37:38 UTC
[activemq-artemis] branch master updated: ARTEMIS-2441 Separate
Lock Files
This is an automated email from the ASF dual-hosted git repository.
clebertsuconic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/master by this push:
new f72409e ARTEMIS-2441 Separate Lock Files
new 128ffc3 This closes #2782
f72409e is described below
commit f72409e38fe9a218bcc4180f41953fef2dc4c40d
Author: Clebert Suconic <cl...@apache.org>
AuthorDate: Tue Jul 30 18:21:28 2019 -0400
ARTEMIS-2441 Separate Lock Files
Certain devices or file systems won't support record level locking.
For that reason I am changing FileLockNodeManager to use separate files (one for each position) instead of using tryLock(position);
A good example for this would be cephFS where channel.tryLock or channel.tryLock works but it fails at a record level.
---
.../activemq/artemis/core/server/NodeManager.java | 2 +-
.../core/server/impl/FileLockNodeManager.java | 50 +++++++++++++++++++---
2 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/NodeManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/NodeManager.java
index e963b22..8ad8e60 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/NodeManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/NodeManager.java
@@ -146,7 +146,7 @@ public abstract class NodeManager implements ActiveMQComponent {
* the *current* nodeID
* </ol>
*/
- protected final synchronized void setUpServerLockFile() throws IOException {
+ protected synchronized void setUpServerLockFile() throws IOException {
File serverLockFile = newFile(SERVER_LOCK_NAME);
boolean fileCreated = false;
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java
index 2044189..e050e94 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java
@@ -18,7 +18,9 @@ package org.apache.activemq.artemis.core.server.impl;
import java.io.File;
import java.io.IOException;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
@@ -34,11 +36,11 @@ public class FileLockNodeManager extends NodeManager {
private static final Logger logger = Logger.getLogger(FileLockNodeManager.class);
- private static final long STATE_LOCK_POS = 0;
+ private static final int STATE_LOCK_POS = 0;
- private static final long LIVE_LOCK_POS = 1;
+ private static final int LIVE_LOCK_POS = 1;
- private static final long BACKUP_LOCK_POS = 2;
+ private static final int BACKUP_LOCK_POS = 2;
private static final long LOCK_LENGTH = 1;
@@ -56,6 +58,8 @@ public class FileLockNodeManager extends NodeManager {
private FileLock backupLock;
+ private final FileChannel[] lockChannels = new FileChannel[3];
+
protected long lockAcquisitionTimeout = -1;
protected boolean interrupted = false;
@@ -83,6 +87,38 @@ public class FileLockNodeManager extends NodeManager {
}
@Override
+ protected synchronized void setUpServerLockFile() throws IOException {
+ super.setUpServerLockFile();
+
+ for (int i = 0; i < 3; i++) {
+ if (lockChannels[i] != null && lockChannels[i].isOpen()) {
+ continue;
+ }
+ File fileLock = newFile("serverlock." + i);
+ if (!fileLock.exists()) {
+ fileLock.createNewFile();
+ }
+ RandomAccessFile randomFileLock = new RandomAccessFile(fileLock, "rw");
+ lockChannels[i] = randomFileLock.getChannel();
+ }
+ }
+
+ @Override
+ public synchronized void stop() throws Exception {
+ for (FileChannel channel : lockChannels) {
+ try {
+ channel.close();
+ } catch (Throwable e) {
+ // I do not want to interrupt a shutdown. If anything is wrong here, just log it
+ // it could be a critical error or something like that throwing the system down
+ logger.warn(e.getMessage(), e);
+ }
+ }
+
+ super.stop();
+ }
+
+ @Override
public boolean isAwaitingFailback() throws Exception {
return getState() == FileLockNodeManager.FAILINGBACK;
}
@@ -172,7 +208,7 @@ public class FileLockNodeManager extends NodeManager {
ActiveMQServerLogger.LOGGER.obtainedLiveLock();
- return new ActivateCallback() {
+ return new CleaningActivateCallback() {
@Override
public void activationComplete() {
try {
@@ -284,10 +320,10 @@ public class FileLockNodeManager extends NodeManager {
return getNodeId();
}
- protected FileLock tryLock(final long lockPos) throws IOException {
+ protected FileLock tryLock(final int lockPos) throws IOException {
try {
logger.debug("trying to lock position: " + lockPos);
- FileLock lock = channel.tryLock(lockPos, LOCK_LENGTH, false);
+ FileLock lock = lockChannels[lockPos].tryLock();
if (lock != null) {
logger.debug("locked position: " + lockPos);
} else {
@@ -300,7 +336,7 @@ public class FileLockNodeManager extends NodeManager {
}
}
- protected FileLock lock(final long lockPosition) throws Exception {
+ protected FileLock lock(final int lockPosition) throws Exception {
long start = System.currentTimeMillis();
boolean isRecurringFailure = false;