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