michaelandrepearce commented on a change in pull request #2547: Patched with 
live lock evaluation
URL: https://github.com/apache/activemq-artemis/pull/2547#discussion_r255168820
 
 

 ##########
 File path: 
artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java
 ##########
 @@ -338,5 +345,104 @@ protected FileLock lock(final long lockPosition) throws 
Exception {
       while (lock == null);
       return lock;
    }
+   
+   private void startLockMonitoring()  {
+          logger.debug("Starting the lock monitor");
+          Thread monitorThread = new Thread(new MonitorLock());
+//        Don't want the exit to block because of the below thread
+          monitorThread.setDaemon(true);
+          monitorThread.start();
+   }
+   
+       private void notifyLostLock() {
+               // Additional check we are not initializing or have no locking 
object anymore because of a shutdown
+               if (lockListeners != null && liveLock != null) { 
+                       Set<LockListener> lockListenersSnapshot = null;
+
+                       // Snapshot of the set because I'm not sure if we can 
trigger concurrent
+                       // modification exception here if we don't
+                       synchronized (lockListeners) {
+                               lockListenersSnapshot = new 
HashSet<>(lockListeners);
+                       }
+
+                       lockListenersSnapshot.forEach(lockListener -> {
+                               try {
+                                       lockListener.lostLock();
+                               } catch (Exception e) {
+                                       // Need to notify everyone so ignore 
any exception
+                               }
+                       });
+               }
+       }
+   
+   
+       public void registerLockListener(LockListener lockListener) {
+               lockListeners.add(lockListener);
+       }
+
+       public void unregisterLockListener(LockListener lockListener) {
+               lockListeners.remove(lockListener);
+       }
+
+   protected final Set<LockListener> lockListeners = 
Collections.synchronizedSet(new HashSet<LockListener>());
+   
+   public abstract class LockListener  {
+          protected abstract void lostLock() throws Exception;
+          
+          protected void unregisterListener()  {
+                  lockListeners.remove(this);
+          }
+   }
+   
+   public class MonitorLock    implements Runnable {
+
+       @Override
+       public void run() {
+               boolean live = (liveLock != null);
+               boolean lostLock;
+               boolean keepMonitoring = true;
+               
+               while (keepMonitoring)  {
+                       lostLock = true;
+                       try {
+                               lostLock = (liveLock != null && 
!liveLock.isValid()) || liveLock == null;
+                               if (!lostLock)  {
+                                       logger.debug("Server still has the 
lock, double check status is live");
+                       // Should be able to retrieve the status unless 
something is wrong
+                       // When EFS is gone, this locks. Which can be solved 
but is a lot of threading work where we need to
+                       // manage the timeout ourselves and interrupt the 
thread used to claim the lock.
+                                       byte state = getState();
+                                       if (state == LIVE)      {
+                                               logger.debug("Status is set to 
live"); 
+                                       } else {
+                                               logger.debug("Status is not 
live");
+                                       }
+                               }
+                       } catch (Exception exception) {
+                               // If something went wrong we probably lost the 
lock
+                               logger.error(exception.getMessage(), exception);
+                               lostLock = true;
+                       }
+                       
+                       if (lostLock)   {
+                               logger.warn("Lost the lock according to the 
monitor, notifying listeners");
+                               notifyLostLock();
+                       }
+                       
+                       try {
+                               Thread.sleep(LOCK_MONITOR_TIMEOUT_MILLIES);
 
 Review comment:
   Use a schedule executor. Instead of sleeping threads blocking and using up a 
thread

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to