package com.workshare.msnos.usvc.api.routing.strategies;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.workshare.msnos.usvc.IMicroservice;
import com.workshare.msnos.usvc.api.routing.ApiEndpoint;
import com.workshare.msnos.usvc.api.routing.RoutingStrategy;
public class CachingRoutingStrategy implements RoutingStrategy {
private static final Logger log = LoggerFactory.getLogger(CachingRoutingStrategy.class);
public static final String SYSP_TIMEOUT = "com.ws.nsnos.usvc.api.routing.strategy.caching.timeout";
private final RoutingStrategy delegate;
private long timeout;
private List<ApiEndpoint> result;
private long lastrun;
private long lastend;
public CachingRoutingStrategy(RoutingStrategy delegate) {
this.delegate = delegate;
this.timeout = getDefaultTimeout();
this.result = Collections.emptyList();
this.lastrun = System.currentTimeMillis();
this.lastend = lastrun - 1;
}
private static long getDefaultTimeout() {
return Long.getLong(SYSP_TIMEOUT, 250l);
}
private void reset() {
this.lastrun = System.currentTimeMillis();
this.lastend = System.currentTimeMillis() + timeout;
}
@Override
public List<ApiEndpoint> select(IMicroservice from, List<ApiEndpoint> apis) {
if (timeout == 0L) {
return delegate.select(from, apis);
}
if (System.currentTimeMillis() > lastend || isFaulty(result)) {
reset();
result = delegate.select(from, apis);
}
return result;
}
public CachingRoutingStrategy withTimeout(int duration, TimeUnit unit) {
this.timeout = TimeUnit.MILLISECONDS.convert(duration, unit);
return this;
}
private boolean isFaulty(List<ApiEndpoint> eps) {
for (ApiEndpoint ep : eps) {
if (ep.isFaulty()) {
log.debug("Current endpoints list is faulty on endpoint {}", ep);
return true;
}
}
return false;
}
}