package com.griddynamics.jagger.dbapi.fetcher;
import com.griddynamics.jagger.dbapi.dto.MetricNameDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
public abstract class ConcurrentMetricDataFetcher<R> extends MetricDataFetcher<R> {
protected int maxSizeOfBatch = 10000;
protected Logger log = LoggerFactory.getLogger(this.getClass());
protected ExecutorService threadPool;
public void setMaxSizeOfBatch(int maxSizeOfBatch) {
this.maxSizeOfBatch = maxSizeOfBatch;
}
@Autowired
@Qualifier("executorService")
public void setThreadPool(ExecutorService threadPool) {
this.threadPool = threadPool;
}
@Override
public Set<R> getResult(List<MetricNameDto> metricNames) {
List<Future<Set<R>>> futureList = new ArrayList<>();
int fromIndex = 0;
while (fromIndex < metricNames.size()) {
int toIndex = fromIndex + maxSizeOfBatch;
if (toIndex > metricNames.size()) {
toIndex = metricNames.size();
}
futureList.add(threadPool.submit(
new Callable<Set<R>>() {
private List<MetricNameDto> metricsToFetch;
private Callable<Set<R>> init(List<MetricNameDto> metricsToFetch) {
this.metricsToFetch = metricsToFetch;
return this;
}
@Override
public Set<R> call() throws Exception {
return fetchData(this.metricsToFetch);
}
}.init(metricNames.subList(fromIndex, toIndex))
));
fromIndex += maxSizeOfBatch;
}
Set<R> result = new HashSet<>();
try {
for (Future<Set<R>> future : futureList) {
result.addAll(future.get());
}
} catch (Exception e) {
log.error("Exception while fetching data", e);
throw new RuntimeException("Exception while getting data from future", e);
}
return result;
}
/**
* method that executes with each callable
* @param metricNames list of metricNames that concrete callable would process
* @return List of results
*/
protected abstract Set<R> fetchData(List<MetricNameDto> metricNames);
}