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;