package io.lumify.core.util;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ThreadedInputStreamProcess<TResult, TData> {
private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(ThreadedInputStreamProcess.class);
private final Thread[] workerThreads;
private final ThreadedTeeInputStreamWorker<TResult, TData>[] workers;
private final String[] workerNames;
public ThreadedInputStreamProcess(String threadNamePrefix,
Collection<? extends ThreadedTeeInputStreamWorker<TResult, TData>> workersCollection) {
this.workers = new ThreadedTeeInputStreamWorker[workersCollection.size()];
this.workerThreads = new Thread[workersCollection.size()];
this.workerNames = new String[workersCollection.size()];
int i = 0;
for (ThreadedTeeInputStreamWorker<TResult, TData> worker : workersCollection) {
this.workers[i] = worker;
this.workerThreads[i] = new Thread(worker);
String workerName = worker.getClass().getName();
this.workerNames[i] = workerName;
this.workerThreads[i].setName(threadNamePrefix + "-" + workerName);
this.workerThreads[i].start();
i++;
}
}
public List<ThreadedTeeInputStreamWorker.WorkResult<TResult>> doWork(InputStream source, TData data) throws Exception {
TeeInputStream teeInputStream = new TeeInputStream(source, this.workerNames);
return doWork(data, teeInputStream);
}
public List<ThreadedTeeInputStreamWorker.WorkResult<TResult>> doWork(InputStream source, TData data, int bufferSize) throws Exception {
TeeInputStream teeInputStream = new TeeInputStream(source, this.workerNames, bufferSize);
return doWork(data, teeInputStream);
}
private List<ThreadedTeeInputStreamWorker.WorkResult<TResult>> doWork(TData data, TeeInputStream teeInputStream) throws Exception {
try {
for (int i = 0; i < this.workers.length; i++) {
this.workers[i].enqueueWork(teeInputStream.getTees()[i], data);
}
teeInputStream.loopUntilTeesAreClosed();
} finally {
teeInputStream.close();
}
ArrayList<ThreadedTeeInputStreamWorker.WorkResult<TResult>> results = new ArrayList<ThreadedTeeInputStreamWorker.WorkResult<TResult>>();
for (ThreadedTeeInputStreamWorker<TResult, TData> worker : this.workers) {
results.add(worker.dequeueResult());
}
return results;
}
public void stop() {
LOGGER.debug("stopping all workers");
for (ThreadedTeeInputStreamWorker<TResult, TData> worker : this.workers) {
worker.stop();
}
for (Thread t : this.workerThreads) {
try {
LOGGER.debug("joining thread: %s", t);
t.join();
} catch (Exception ex) {
LOGGER.error("Could not join thread: " + t, ex);
}
}
}
}