/** * Not reentrant lock acquisition operation (ie {@link #tryAcquire()}). * It tries to acquire the lock until will succeed (ie {@link AcquireResult#Done}), got interrupted (ie {@link AcquireResult#Exit}) * or exceed {@code tryAcquireTimeoutMillis}. * After each failed attempt is performed a {@link Pauser#idle} call. * If the specified timeout is <=0 then it behaves as {@link #tryAcquire(ExitCondition, Pauser)}. */ default AcquireResult tryAcquire(long tryAcquireTimeoutMillis, Pauser pauser, ExitCondition exitCondition) { if (tryAcquireTimeoutMillis < 0) { return tryAcquire(exitCondition, pauser); } final long timeoutInNanosecond = TimeUnit.MILLISECONDS.toNanos(tryAcquireTimeoutMillis); final long startAcquire = System.nanoTime(); while (exitCondition.keepRunning()) { if (tryAcquire()) { return AcquireResult.Done; } else if (System.nanoTime() - startAcquire >= timeoutInNanosecond) { return AcquireResult.Timeout; } else { pauser.idle(); //check before doing anything if time is expired if (System.nanoTime() - startAcquire >= timeoutInNanosecond) { return AcquireResult.Timeout; } } } return AcquireResult.Exit; }
final long idleMillis = 1000; final long millisToAcquireLock = writesPerProducer * (producers - 1) * idleMillis; final LeaseLock.Pauser pauser = LeaseLock.Pauser.sleep(idleMillis, TimeUnit.MILLISECONDS); final CountDownLatch finished = new CountDownLatch(producers); final LeaseLock[] locks = new LeaseLock[producers];
private JdbcNodeManager(Supplier<? extends SharedStateManager> sharedStateManagerFactory, long lockRenewPeriodMillis, long lockAcquisitionTimeoutMillis, ScheduledExecutorService scheduledExecutorService, ExecutorFactory executorFactory, IOCriticalErrorListener ioCriticalErrorListener) { super(false, null); this.lockAcquisitionTimeoutMillis = lockAcquisitionTimeoutMillis; this.pauser = LeaseLock.Pauser.sleep(Math.min(lockRenewPeriodMillis, MAX_PAUSE_MILLIS), TimeUnit.MILLISECONDS); this.sharedStateManagerFactory = sharedStateManagerFactory; this.scheduledLiveLockFactory = () -> ScheduledLeaseLock.of( scheduledExecutorService, executorFactory != null ? executorFactory.getExecutor() : null, "live", this.sharedStateManager.liveLock(), lockRenewPeriodMillis, ioCriticalErrorListener); this.scheduledBackupLockFactory = () -> ScheduledLeaseLock.of( scheduledExecutorService, executorFactory != null ? executorFactory.getExecutor() : null, "backup", this.sharedStateManager.backupLock(), lockRenewPeriodMillis, ioCriticalErrorListener); this.ioCriticalErrorListener = ioCriticalErrorListener; this.sharedStateManager = null; this.scheduledLiveLock = null; this.scheduledBackupLock = null; }
@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"); } }
/** * Not reentrant lock acquisition operation (ie {@link #tryAcquire()}). * It tries to acquire the lock until will succeed (ie {@link AcquireResult#Done})or got interrupted (ie {@link AcquireResult#Exit}). * After each failed attempt is performed a {@link Pauser#idle} call. */ default AcquireResult tryAcquire(ExitCondition exitCondition, Pauser pauser) { while (exitCondition.keepRunning()) { if (tryAcquire()) { return AcquireResult.Done; } else { pauser.idle(); } } return AcquireResult.Exit; }
@Override public void awaitLiveStatus() { LOGGER.debug("ENTER awaitLiveStatus"); try { while (readSharedState() != SharedStateManager.State.LIVE) { pauser.idle(); } } finally { LOGGER.debug("EXIT awaitLiveStatus"); } }