package org.solrmarc.driver;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.marc4j.marc.Record;
import org.solrmarc.tools.SolrMarcIndexerException;
public class IndexerWorker implements Runnable
{
private final static Logger logger = Logger.getLogger(IndexerWorker.class);
private final BlockingQueue<RecordAndCnt> readQ;
private final BlockingQueue<RecordAndDoc> docQ;
private Indexer indexer;
private MarcReaderThread readerThread;
private int threadCount;
private boolean doneWorking = false;
private boolean interrupted = false;
public IndexerWorker(MarcReaderThread readerThread, BlockingQueue<RecordAndCnt> readQ, BlockingQueue<RecordAndDoc> docQ, Indexer indexer, int threadCount)
{
this.readerThread = readerThread;
this.readQ = readQ;
this.docQ = docQ;
this.indexer = indexer;
this.threadCount = threadCount;
this.doneWorking = false;
}
public boolean isDoneWorking()
{
return doneWorking;
}
public void setInterrupted()
{
interrupted = true;
}
public boolean isInterrupted()
{
return(interrupted);
}
@Override
public void run()
{
// if this isn't the first Indexer Worker Thread make a thread safe instance duplicate of the indexer
// this primarily means making a new instance object for each External Method class
if (threadCount > 0)
{
indexer = (threadCount == 0) ? indexer : indexer.makeThreadSafeCopy();
}
Thread.currentThread().setName("RecordIndexer-Thread-"+threadCount);
while ((! readerThread.isDoneReading(false) || !readQ.isEmpty()) && !readerThread.isInterrupted() && !isInterrupted() )
{
try
{
RecordAndCnt recordAndCnt = readQ.poll(100, TimeUnit.MILLISECONDS);
if (recordAndCnt == null) continue;
int count = recordAndCnt.getCnt();
Record record = recordAndCnt.getRecord();
if (isInterrupted()) break;
RecordAndDoc recDoc = null;
try {
recDoc = indexer.getIndexDoc(record, count);
}
catch (SolrMarcIndexerException smie)
{
indexer.shutDown(false);
break;
}
if (recDoc == null) continue;
if (isInterrupted()) break;
try {
docQ.put(recDoc);
}
catch (InterruptedException ie)
{
Thread.currentThread().interrupt();
break;
}
}
catch (InterruptedException e)
{
logger.warn("Interrupted while waiting for a record to appear in the read queue.");
interrupted = true;
Thread.currentThread().interrupt();
}
}
doneWorking = true;
}
}