void waitForCurrentOperations(Logger alertLogger, long warnMS, long severeAlertMS) { // this may wait longer than it should if the membership version changes, dumping // more operations into the previousVersionOpCount final long startTime = System.currentTimeMillis(); final long warnTime = startTime + warnMS; final long severeAlertTime = startTime + severeAlertMS; boolean warned = false; boolean severeAlertIssued = false; while (operationsAreInProgress()) { // The advisor's close() method will set the pVOC to zero. This loop // must not terminate due to cache closure until that happens. try { Thread.sleep(50); } catch (InterruptedException e) { throw new GemFireIOException("State flush interrupted"); } long now = System.currentTimeMillis(); if ((!warned) && System.currentTimeMillis() >= warnTime) { warned = true; logWaitOnOperationsWarning(alertLogger, warnMS); } else if (warned && !severeAlertIssued && (now >= severeAlertTime)) { logWaitOnOperationsSevere(alertLogger, severeAlertMS); severeAlertIssued = true; } } if (warned) { alertLogger.info("Wait for current operations completed"); } }
@Override void membershipVersionChanged() { super.membershipVersionChanged(); previousVersionOperationThreads .putAll(currentVersionOperationThreads); currentVersionOperationThreads.clear(); }
} else { if (!membershipClosed) { operationMonitor.initNewProfile(newProfile); operationMonitor.forceNewMembershipVersion();
/** * Free up resources used by this advisor once it is no longer being used. * * @since GemFire 3.5 */ public void close() { try { synchronized (this) { this.membershipClosed = true; operationMonitor.close(); } getDistributionManager().removeMembershipListener(this.ml); } catch (CancelException e) { // if distribution has stopped, above is a no-op. } catch (IllegalArgumentException ignore) { // this is thrown if the listener is no longer registered } }
/** * This method must be invoked when messages for an operation have been put in the * DistributionManager's outgoing queue. * * @param version The membership version returned by startOperation * @since GemFire 5.1 */ synchronized void endOperation(long version) { if (version == membershipVersion) { currentVersionOpCount--; logEndOperation(true); } else { previousVersionOpCount--; logEndOperation(false); } }
/** * this method must be invoked at the start of every operation that can modify the state of * resource. The return value must be recorded and sent to the advisor in an endOperation * message when messages for the operation have been put in the DistributionManager's outgoing * "queue". * * @return the current membership version for this advisor * @since GemFire 5.1 */ synchronized long startOperation() { logNewOperation(); currentVersionOpCount++; return membershipVersion; }
/** * Create a new version of the membership profile set. This is used in flushing state out of the * VM for previous versions of the set. * * @since GemFire 5.1 */ synchronized void forceNewMembershipVersion() { if (!closed) { incrementMembershipVersion(); previousVersionOpCount += currentVersionOpCount; currentVersionOpCount = 0; membershipVersionChanged(); } }
synchronized void initNewProfile(Profile newProfile) { membershipVersion++; newProfile.initialMembershipVersion = membershipVersion; previousVersionOpCount = previousVersionOpCount + currentVersionOpCount; currentVersionOpCount = 0; membershipVersionChanged(); }
/** * Create a new version of the membership profile set. This is used in flushing state out of the * VM for previous versions of the set. * * @since GemFire 5.1 */ public void forceNewMembershipVersion() { operationMonitor.forceNewMembershipVersion(); }
@Override void logWaitOnOperationsWarning(Logger alertLogger, long warnMS) { super.logWaitOnOperationsWarning(alertLogger, warnMS); synchronized (this) { logger .debug("Waiting for these threads: {}", previousVersionOperationThreads); logger .debug("New version threads are {}", currentVersionOperationThreads); } }
@Override void logWaitOnOperationsSevere(Logger alertLogger, long severeAlertMS) { super.logWaitOnOperationsSevere(alertLogger, severeAlertMS); synchronized (this) { logger .debug("Waiting for these threads: {}", previousVersionOperationThreads); logger .debug("New version threads are {}", currentVersionOperationThreads); } }
/** * This method must be invoked when messages for an operation have been put in the * DistributionManager's outgoing queue. * * @param version The membership version returned by startOperation * @since GemFire 5.1 */ public void endOperation(long version) { operationMonitor.endOperation(version); }