package org.solrmarc.driver; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.BlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; import org.marc4j.MarcReader; public class MarcReaderThread extends Thread { private final static Logger logger = Logger.getLogger(MarcReaderThread.class); private final MarcReader reader; private final Indexer indexer; private final BlockingQueue<RecordAndCnt> readQ; private boolean doneReading = false; public MarcReaderThread(final MarcReader reader, final Indexer indexer, final BlockingQueue<RecordAndCnt> readQ, AtomicInteger cnts[]) { super("MarcReader-Thread"); this.reader = reader; this.indexer = indexer; this.readQ = readQ; } @Override public void run() { RecordAndCnt recordAndCnt = null; while (!Thread.currentThread().isInterrupted()) { recordAndCnt = indexer.getRecord(reader); if (recordAndCnt == null) break; logger.debug("record read : " + recordAndCnt.getRecord().getControlNumber()); try { readQ.put(recordAndCnt); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } if (Thread.currentThread().isInterrupted()) { flushReadQueue(recordAndCnt); } doneReading = true; } private void flushReadQueue(RecordAndCnt recordAndCnt) { Collection<RecordAndCnt> discardedRecords = new ArrayList<>(); readQ.drainTo(discardedRecords); if (discardedRecords.size() > 0) { String id = discardedRecords.iterator().next().getRecord().getControlNumber(); logger.warn("Reader Thread: discarding unprocessed records starting with record: "+ id); } else { String id = (recordAndCnt != null && recordAndCnt.getRecord() != null) ? recordAndCnt.getRecord().getControlNumber() : "<none>"; logger.warn("Reader Thread Interrupted: last record processed was: "+ id); } indexer.addToCnt(0, -discardedRecords.size()); } public boolean isDoneReading(boolean shuttingDown) { if (shuttingDown && doneReading && readQ.size() > 0) { flushReadQueue(null); } return doneReading; } }