package org.gbif.checklistbank.nub.source; import org.gbif.checklistbank.iterable.CloseableIterable; import org.gbif.checklistbank.iterable.FutureIterator; import org.gbif.utils.concurrent.ExecutorUtils; import org.gbif.utils.concurrent.NamedThreadFactory; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Base class for nub source lists that deals with the iteratore and async loading of sources. */ public class NubSourceList implements CloseableIterable<NubSource> { private static final Logger LOG = LoggerFactory.getLogger(ClbSourceList.class); protected final ExecutorService exec; protected List<Future<NubSource>> futures = Lists.newArrayList(); private final boolean parseNames; public NubSourceList(boolean parseNames) { this.parseNames = parseNames; //exec = new DirectExecutor(); exec = Executors.newSingleThreadExecutor(new NamedThreadFactory("source-loader")); } public NubSourceList(List<? extends NubSource> sources, boolean parseNames) { this(parseNames); submitSources(sources); } /** * Call this method from subclasses once to submit all nub resources to this list. * The list will be submitted to a background loaders that calls init() on each NubSource asynchroneously. */ protected void submitSources(List<? extends NubSource> sources) { LOG.info("Found {} backbone sources", sources.size()); // submit loader jobs ExecutorCompletionService ecs = new ExecutorCompletionService(exec); for (NubSource src : sources) { futures.add(ecs.submit(new LoadSource(src, parseNames))); } } @Override public Iterator<NubSource> iterator() { return new FutureIterator<NubSource>(futures); } @Override public void close() { ExecutorUtils.stop(exec, 10, TimeUnit.SECONDS); } }