org.infinispan.xsite.OfflineStatus Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.infinispan.xsite;
import net.jcip.annotations.ThreadSafe;
import org.infinispan.configuration.cache.TakeOfflineConfiguration;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import java.util.concurrent.TimeUnit;
/**
* Keeps state needed for knowing when a site needs to be taken offline.
*
* Thread safety: This class is updated from multiple threads so the access to it is synchronized by object's intrinsic
* lock.
*
* Impl detail: As this class's state changes constantly, the equals and hashCode haven't been overridden. This
* shouldn't affect performance significantly as the number of site backups should be relatively small (1-3).
*
* @author Mircea Markus
* @since 5.2
*/
@ThreadSafe
public class OfflineStatus {
private static Log log = LogFactory.getLog(OfflineStatus.class);
private volatile TakeOfflineConfiguration takeOffline;
private boolean recordingOfflineStatus = false;
private long firstFailureTime;
private int failureCount;
private volatile boolean forceOffline = false;
public OfflineStatus(TakeOfflineConfiguration takeOfflineConfiguration) {
this.takeOffline = takeOfflineConfiguration;
}
public synchronized void updateOnCommunicationFailure(long sendTimeMillis) {
if (!recordingOfflineStatus) {
recordingOfflineStatus = true;
firstFailureTime = sendTimeMillis;
}
failureCount++;
}
public synchronized boolean isOffline() {
if (forceOffline)
return true;
if (!recordingOfflineStatus)
return false;
if (takeOffline.minTimeToWait() > 0) { //min time to wait is enabled
if (!minTimeHasElapsed()) return false;
}
if (takeOffline.afterFailures() > 0) {
if (takeOffline.afterFailures() <= failureCount) {
return true;
} else {
return false;
}
} else {
log.trace("Site is failed: minTimeToWait elapsed and we don't have a min failure number to wait for.");
return true;
}
}
public synchronized boolean minTimeHasElapsed() {
if (takeOffline.minTimeToWait() <= 0)
throw new IllegalStateException("Cannot invoke this method if minTimeToWait is not enabled");
long millis = millisSinceFirstFailure();
if (millis >= takeOffline.minTimeToWait()) {
log.tracef("The minTimeToWait has passed: minTime=%s, timeSinceFirstFailure=%s",
takeOffline.minTimeToWait(), millis);
return true;
}
return false;
}
public synchronized long millisSinceFirstFailure() {
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - firstFailureTime;
}
public synchronized boolean bringOnline() {
if (!isOffline()) return false;
reset();
return true;
}
public synchronized int getFailureCount() {
return failureCount;
}
public synchronized boolean isEnabled() {
return takeOffline.enabled();
}
/**
* Configures the site to use the supplied configuration for determining when to take a site offline.
* Also triggers a state reset.
*/
public void amend(TakeOfflineConfiguration takeOffline) {
this.takeOffline = takeOffline;
reset();
}
public void reset() {
recordingOfflineStatus = false;
failureCount = 0;
forceOffline = false;
}
public TakeOfflineConfiguration getTakeOffline() {
return takeOffline;
}
public boolean forceOffline() {
if (isOffline()) return false;
forceOffline = true;
return true;
}
@Override
public String toString() {
return "OfflineStatus{" +
"takeOffline=" + takeOffline +
", recordingOfflineStatus=" + recordingOfflineStatus +
", firstFailureTime=" + firstFailureTime +
", forceOffline=" + forceOffline +
", failureCount=" + failureCount +
'}';
}
public void amend(Integer afterFailures, Long minTimeToWait) {
TakeOfflineConfiguration existing = getTakeOffline();
int newAfterFailures = afterFailures == null ? existing.afterFailures() : afterFailures;
long newMinTieToWait = minTimeToWait == null ? existing.minTimeToWait() : minTimeToWait;
TakeOfflineConfiguration newConfig = new TakeOfflineConfiguration(newAfterFailures, newMinTieToWait);
amend(newConfig);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy