package com.networknt.balance;
import com.networknt.registry.URL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Round Robin Loadbalance will pick up a url from a list of urls one by one
* for each call. It will distributed the load equally to all urls in the list.
*
* This class has an instance variable called idx which is AtomicInteger and it
* increases for every select call to make sure all urls in the list will have
* an opportunity to be selected.
*
* The assumption for round robin is based on all service will have the same
* hardware/cloud resource configuration so that they can be treated as the
* same priority without any weight.
*
* Created by steve on 2016-12-07.
*/
public class RoundRobinLoadBalance implements LoadBalance {
static Logger logger = LoggerFactory.getLogger(RoundRobinLoadBalance.class);
public RoundRobinLoadBalance() {
if(logger.isInfoEnabled()) logger.info("A RoundRobinLoadBalance instance is started");
}
private AtomicInteger idx = new AtomicInteger(0);
/**
* Round robin requestKey is not used as it should be null, the url will
* be selected from the list base on an instance idx so every url has the
* same priority.
*
* @param urls List
* @param requestKey String
* @return
*/
@Override
public URL select(List<URL> urls, String requestKey) {
URL url = null;
if (urls.size() > 1) {
url = doSelect(urls);
} else if (urls.size() == 1) {
url = urls.get(0);
}
return url;
}
protected URL doSelect(List<URL> urls) {
int index = getNextPositive();
for (int i = 0; i < urls.size(); i++) {
URL url = urls.get((i + index) % urls.size());
if (url != null) {
return url;
}
}
return null;
}
// get positive int
private int getNextPositive() {
return getPositive(idx.incrementAndGet());
}
}