@Override public boolean isAwaitingFailback() throws Exception { LOGGER.debug("ENTER isAwaitingFailback"); try { return readSharedState() == SharedStateManager.State.FAILING_BACK; } finally { LOGGER.debug("EXIT isAwaitingFailback"); } }
@Override public void awaitLiveStatus() { LOGGER.debug("ENTER awaitLiveStatus"); try { while (readSharedState() != SharedStateManager.State.LIVE) { pauser.idle(); } } finally { LOGGER.debug("EXIT awaitLiveStatus"); } }
@Override public void awaitLiveNode() throws Exception { LOGGER.debug("ENTER awaitLiveNode"); try { boolean liveWhileLocked = false; while (!liveWhileLocked) { //check first without holding any lock final SharedStateManager.State state = readSharedState(); if (state == SharedStateManager.State.LIVE) { //verify if the state is live while holding the live node lock too liveWhileLocked = lockLiveAndCheckLiveState(); } else { LOGGER.debugf("state while awaiting live node: %s", state); } if (!liveWhileLocked) { checkInterrupted(() -> "awaitLiveNode got interrupted!"); pauser.idle(); } } //state is LIVE and live lock is acquired and valid LOGGER.debugf("acquired live node lock while state is %s: starting scheduledLiveLock", SharedStateManager.State.LIVE); this.scheduledLiveLock.start(); } finally { LOGGER.debug("EXIT awaitLiveNode"); } }
/** * Lock live node and check for a live state, taking care to renew it (if needed) or releasing it otherwise */ private boolean lockLiveAndCheckLiveState() throws Exception { lock(this.scheduledLiveLock.lock()); final long acquiredOn = System.nanoTime(); boolean liveWhileLocked = false; //check if the state is live final SharedStateManager.State stateWhileLocked; try { stateWhileLocked = readSharedState(); } catch (Throwable t) { LOGGER.error("error while holding the live node lock and tried to read the shared state", t); this.scheduledLiveLock.lock().release(); throw t; } if (stateWhileLocked == SharedStateManager.State.LIVE) { renewLiveLockIfNeeded(acquiredOn); liveWhileLocked = true; } else { LOGGER.debugf("state is %s while holding the live lock: releasing live lock", stateWhileLocked); //state is not live: can (try to) release the lock this.scheduledLiveLock.lock().release(); } return liveWhileLocked; }