com.github.phantomthief.failover.impl.RecoverableCheckFailover Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simple-failover Show documentation
Show all versions of simple-failover Show documentation
A simple failover library for Java
package com.github.phantomthief.failover.impl;
import static com.github.phantomthief.failover.util.SharedCheckExecutorHolder.getInstance;
import static com.github.phantomthief.util.MoreSuppliers.lazy;
import static com.google.common.collect.EvictingQueue.create;
import static java.lang.System.currentTimeMillis;
import static java.util.Collections.emptySet;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.stream.Collectors.toList;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.Closeable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ScheduledFuture;
import java.util.function.Predicate;
import org.slf4j.Logger;
import com.github.phantomthief.failover.Failover;
import com.github.phantomthief.util.MoreSuppliers.CloseableSupplier;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.EvictingQueue;
/**
* 一个简易的failover/failback策略类
* failover条件是一段时间内出错次数超过一个阈值
* failback策略是定期检查可用
*
* @author w.vela
*/
@Deprecated
public class RecoverableCheckFailover implements Failover, Closeable {
private static final Logger logger = getLogger(RecoverableCheckFailover.class);
private final List original;
private final long failDuration;
private final Set failedList = new CopyOnWriteArraySet<>();
private final LoadingCache> failCountMap;
private final boolean returnOriginalWhileAllFailed;
private final CloseableSupplier> recoveryFuture;
private volatile boolean closed;
RecoverableCheckFailover(List original, Predicate checker, int failCount,
long failDuration, long recoveryCheckDuration, boolean returnOriginalWhileAllFailed) {
this.returnOriginalWhileAllFailed = returnOriginalWhileAllFailed;
this.original = original;
this.failDuration = failDuration;
this.failCountMap = CacheBuilder.newBuilder().weakKeys()
.build(new CacheLoader>() {
@Override
public EvictingQueue load(T key) {
return create(failCount);
}
});
recoveryFuture = lazy(() -> getInstance().scheduleWithFixedDelay(() -> {
if (closed) {
tryCloseScheduler();
return;
}
if (failedList.isEmpty()) {
return;
}
try {
// 考虑到COWArraySet不支持iterator.remove,所以这里使用搜集->统一清理的策略
List covered = failedList.stream()
.filter(checker)
.peek(obj -> logger.info("obj:{} is recovered during test.", obj))
.collect(toList());
failedList.removeAll(covered);
} catch (Throwable e) {
logger.error("Ops.", e);
}
}, recoveryCheckDuration, recoveryCheckDuration, MILLISECONDS));
}
public static RecoverableCheckFailoverBuilder