blob: f493f6926e074cfb0d616dd7a032e21ed0aa3edd [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.ha;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicLong;
public final class HAResourceCounter {
private AtomicLong activityCheckCounter = new AtomicLong(0);
private AtomicLong activityCheckFailureCounter = new AtomicLong(0);
private AtomicLong recoveryOperationCounter = new AtomicLong(0);
private Long firstHealthCheckFailureTimestamp;
private Long lastActivityCheckTimestamp;
private Long degradedTimestamp;
private Long recoverTimestamp;
private Future<Boolean> recoveryFuture;
private Future<Boolean> fenceFuture;
public long getActivityCheckCounter() {
return activityCheckCounter.get();
}
public long getRecoveryCounter() {
return recoveryOperationCounter.get();
}
public synchronized void incrActivityCounter(final boolean isFailure) {
activityCheckCounter.incrementAndGet();
if (isFailure) {
activityCheckFailureCounter.incrementAndGet();
}
}
public synchronized void incrRecoveryCounter() {
recoveryOperationCounter.incrementAndGet();
}
public synchronized void resetActivityCounter() {
activityCheckCounter.set(0);
activityCheckFailureCounter.set(0);
}
public synchronized void resetRecoveryCounter() {
recoverTimestamp = null;
recoveryFuture = null;
recoveryOperationCounter.set(0);
}
public synchronized void resetSuspectTimestamp() {
firstHealthCheckFailureTimestamp = null;
}
public boolean hasActivityThresholdExceeded(final double failureRatio) {
return activityCheckFailureCounter.get() > (activityCheckCounter.get() * failureRatio);
}
public synchronized boolean canPerformActivityCheck(final Long activityCheckInterval) {
if (lastActivityCheckTimestamp == null || (System.currentTimeMillis() - lastActivityCheckTimestamp) > (activityCheckInterval * 1000)) {
lastActivityCheckTimestamp = System.currentTimeMillis();
return true;
}
return false;
}
public boolean canRecheckActivity(final Long maxDegradedPeriod) {
return degradedTimestamp == null || (System.currentTimeMillis() - degradedTimestamp) > (maxDegradedPeriod * 1000);
}
public boolean canExitRecovery(final Long maxRecoveryWaitPeriod) {
return recoverTimestamp != null && (System.currentTimeMillis() - recoverTimestamp) > (maxRecoveryWaitPeriod * 1000);
}
public long getSuspectTimeStamp() {
if (firstHealthCheckFailureTimestamp == null) {
firstHealthCheckFailureTimestamp = System.currentTimeMillis();
}
return firstHealthCheckFailureTimestamp;
}
public synchronized void markResourceSuspected() {
firstHealthCheckFailureTimestamp = System.currentTimeMillis();
}
public synchronized void markResourceDegraded() {
degradedTimestamp = System.currentTimeMillis();
}
public synchronized void markRecoveryStarted() {
if (recoverTimestamp == null) {
recoverTimestamp = System.currentTimeMillis();
}
}
public synchronized void markRecoveryCompleted() {
recoverTimestamp = null;
recoveryFuture = null;
}
public void setRecoveryFuture(final Future<Boolean> future) {
recoveryFuture = future;
}
public boolean canAttemptRecovery() {
return recoveryFuture == null || recoveryFuture.isDone();
}
public void setFenceFuture(final Future<Boolean> future) {
fenceFuture = future;
}
public boolean canAttemptFencing() {
return fenceFuture == null || fenceFuture.isDone();
}
}