/** * It release the lock itself and all the resources used by it (eg connections, file handlers) */ @Override default void close() throws Exception { release(); }
@Override public void stopBackup() throws Exception { LOGGER.debug("ENTER stopBackup"); try { if (this.scheduledBackupLock.isStarted()) { LOGGER.debug("scheduledBackupLock is running: stop it and release backup lock"); this.scheduledBackupLock.stop(); this.scheduledBackupLock.lock().release(); } else { LOGGER.debug("scheduledBackupLock is not running"); } } finally { LOGGER.debug("EXIT stopBackup"); } }
@Override public void releaseBackup() throws Exception { LOGGER.debug("ENTER releaseBackup"); try { if (this.scheduledBackupLock.isStarted()) { LOGGER.debug("scheduledBackupLock is running: stop it and release backup lock"); this.scheduledBackupLock.stop(); this.scheduledBackupLock.lock().release(); } else { LOGGER.debug("scheduledBackupLock is not running"); } } finally { LOGGER.debug("EXIT releaseBackup"); } }
@Override public void crashLiveServer() throws Exception { LOGGER.debug("ENTER crashLiveServer"); try { if (this.scheduledLiveLock.isStarted()) { LOGGER.debug("scheduledLiveLock is running: request stop it and release live lock"); this.scheduledLiveLock.stop(); this.scheduledLiveLock.lock().release(); } else { LOGGER.debug("scheduledLiveLock is not running"); } } finally { LOGGER.debug("EXIT crashLiveServer"); } }
@Override public void pauseLiveServer() throws Exception { LOGGER.debug("ENTER pauseLiveServer"); try { if (scheduledLiveLock.isStarted()) { LOGGER.debug("scheduledLiveLock is running: set paused shared state, stop it and release live lock"); setPaused(); scheduledLiveLock.stop(); scheduledLiveLock.lock().release(); } else { LOGGER.debug("scheduledLiveLock is not running: try renew live lock"); if (scheduledLiveLock.lock().renew()) { LOGGER.debug("live lock renewed: set paused shared state and release live lock"); setPaused(); scheduledLiveLock.lock().release(); } else { final IllegalStateException e = new IllegalStateException("live lock can't be renewed"); ioCriticalErrorListener.onIOException(e, "live lock can't be renewed on pauseLiveServer", null); throw e; } } } finally { LOGGER.debug("EXIT pauseLiveServer"); } }
/** * 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; }
@Test public void shouldRenewAcquiredLock() throws InterruptedException { final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(10)); Assert.assertTrue("lock is not owned by anyone", lock.tryAcquire()); try { Assert.assertTrue("lock is owned", lock.renew()); } finally { lock.release(); } }
@Test public void shouldOtherAcquireExpiredLock() throws InterruptedException { final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(1)); Assert.assertTrue("lock is not owned by anyone", lock.tryAcquire()); try { Thread.sleep(lock.expirationMillis() * 2); Assert.assertFalse("lock is already expired", lock.isHeldByCaller()); Assert.assertFalse("lock is already expired", lock.isHeld()); final LeaseLock otherLock = lock(TimeUnit.SECONDS.toMillis(10)); try { Assert.assertTrue("lock is already expired", otherLock.tryAcquire()); } finally { otherLock.release(); } } finally { lock.release(); } }
@Test public void shouldNotRenewLockAcquiredByOthers() throws InterruptedException { final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(1)); Assert.assertTrue("lock is not owned by anyone", lock.tryAcquire()); try { Thread.sleep(lock.expirationMillis() * 2); Assert.assertFalse("lock is already expired", lock.isHeldByCaller()); Assert.assertFalse("lock is already expired", lock.isHeld()); final LeaseLock otherLock = lock(TimeUnit.SECONDS.toMillis(10)); Assert.assertTrue("lock is already expired", otherLock.tryAcquire()); try { Assert.assertFalse("lock is owned by others", lock.renew()); } finally { otherLock.release(); } } finally { lock.release(); } } }
@Test public void shouldAcquireLock() { final LeaseLock lock = lock(); final boolean acquired = lock.tryAcquire(); Assert.assertTrue("Must acquire the lock!", acquired); try { Assert.assertTrue("The lock is been held by the caller!", lock.isHeldByCaller()); } finally { lock.release(); } }
@Test public void shouldNotAcquireLockTwice() { final LeaseLock lock = lock(); Assert.assertTrue("Must acquire the lock", lock.tryAcquire()); try { Assert.assertFalse("lock already acquired", lock.tryAcquire()); } finally { lock.release(); } }
@Test public void shouldAcquireExpiredLock() throws InterruptedException { final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(1)); Assert.assertTrue("lock is not owned by anyone", lock.tryAcquire()); try { Thread.sleep(lock.expirationMillis() * 2); Assert.assertFalse("lock is already expired", lock.isHeldByCaller()); Assert.assertFalse("lock is already expired", lock.isHeld()); Assert.assertTrue("lock is already expired", lock.tryAcquire()); } finally { lock.release(); } }
@Test public void shouldRenewExpiredLockNotAcquiredByOthers() throws InterruptedException { final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(1)); Assert.assertTrue("lock is not owned by anyone", lock.tryAcquire()); try { Thread.sleep(lock.expirationMillis() * 2); Assert.assertFalse("lock is already expired", lock.isHeldByCaller()); Assert.assertFalse("lock is already expired", lock.isHeld()); Assert.assertTrue("lock is owned", lock.renew()); } finally { lock.release(); } }
@Test public void shouldNotRenewReleasedLock() throws InterruptedException { final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(10)); Assert.assertTrue("lock is not owned by anyone", lock.tryAcquire()); lock.release(); Assert.assertFalse("lock is already released", lock.isHeldByCaller()); Assert.assertFalse("lock is already released", lock.isHeld()); Assert.assertFalse("lock is already released", lock.renew()); }
@Test public void shouldNotAcquireLockWhenAlreadyHeldByOthers() { final LeaseLock lock = lock(); Assert.assertTrue("Must acquire the lock", lock.tryAcquire()); try { Assert.assertTrue("Lock held by the caller", lock.isHeldByCaller()); final LeaseLock failingLock = lock(); Assert.assertFalse("lock already held by other", failingLock.tryAcquire()); Assert.assertFalse("lock already held by other", failingLock.isHeldByCaller()); Assert.assertTrue("lock already held by other", failingLock.isHeld()); } finally { lock.release(); } }