private void renewLiveLockIfNeeded(final long acquiredOn) { final long acquiredMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - acquiredOn); if (acquiredMillis > this.scheduledLiveLock.renewPeriodMillis()) { if (!this.scheduledLiveLock.lock().renew()) { final IllegalStateException e = new IllegalStateException("live lock can't be renewed"); ioCriticalErrorListener.onIOException(e, "live lock can't be renewed", null); throw e; } } }
@Override public void run() { final long lastRenewStart = this.lastLockRenewStart; final long renewStart = System.nanoTime(); try { if (!this.lock.renew()) { ioCriticalErrorListener.onIOException(new IllegalStateException(lockName + " lock can't be renewed"), "Critical error while on " + lockName + " renew", null); } } catch (Throwable t) { ioCriticalErrorListener.onIOException(t, "Critical error while on " + lockName + " renew", null); throw t; } //logic to detect slowness of DB and/or the scheduled executor service detectAndReportRenewSlowness(lockName, lastRenewStart, renewStart, renewPeriodMillis, lock.expirationMillis()); this.lastLockRenewStart = renewStart; }
@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"); } }
@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 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 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(); } } }