package hu.sztaki.ilab.longneck.process.task; import hu.sztaki.ilab.longneck.Record; import hu.sztaki.ilab.longneck.bootstrap.PropertyUtils; import hu.sztaki.ilab.longneck.process.access.Target; import java.util.List; import java.util.Properties; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; /** * * @author Molnár Péter <molnarp@sztaki.mta.hu> */ public class TargetWriter extends AbstractTask implements Runnable { /** Log to write messages to. */ private final Logger LOG = Logger.getLogger(TargetWriter.class); /** Wait timeout for targetQueue reads in milliseconds. */ private final int queueReadTimeout; /** Enable truncating the datastore before writing new records. */ private final boolean truncateBeforeWriteEnabled; /** The target write queue. */ private final BlockingQueue<QueueItem> targetQueue; /** The target to write to. */ private final Target target; /** Enable running of the thread. */ private volatile boolean running = true; public TargetWriter(BlockingQueue<QueueItem> inQueue, Target target, Properties runtimeProperties) { this.targetQueue = inQueue; this.target = target; measureTimeEnabled = PropertyUtils.getBooleanProperty( runtimeProperties, "measureTimeEnabled", false); truncateBeforeWriteEnabled = PropertyUtils.getBooleanProperty( runtimeProperties, "truncateBeforeWrite", false); queueReadTimeout = PropertyUtils.getIntProperty( runtimeProperties, "targetWriter.queueReadTimeout", 100); } @Override public void run() { super.run(); LOG.info("Starting up."); boolean waitForMoreRecords = true; // Initialize output records data structure List<Record> outRecords; QueueItem item; // Initialize target target.init(); try { if (truncateBeforeWriteEnabled) { target.truncate(); } while (running && waitForMoreRecords) { // Query item item = targetQueue.poll(queueReadTimeout, TimeUnit.MILLISECONDS); if (item == null) { continue; } if (item.isNoMoreRecords()) { waitForMoreRecords = false; } // Clear output records outRecords = item.getRecords(); stats.in += outRecords.size(); // Write records to output if (outRecords.size() > 0) { // Append records to output target.appendRecords(outRecords); stats.out += outRecords.size(); } } } catch (InterruptedException ex) { LOG.error("Interrupted.", ex); } catch (Exception ex) { LOG.fatal("Fatal error during processing.", ex); } target.close(); // Log timings if (measureTimeEnabled) { stats.totalTimeMillis = this.getTotalTime(); stats.blockedTimeMillis = mxBean.getThreadInfo(Thread.currentThread().getId()).getBlockedTime(); } stats.setMeasureTimeEnabled(measureTimeEnabled); LOG.info(stats.toString()); LOG.info("Shutting down."); } public boolean isRunning() { return running; } public void setRunning(boolean running) { this.running = running; } public Target getTarget() { return target; } public BlockingQueue<QueueItem> getTargetQueue() { return targetQueue; } public int getQueueReadTimeout() { return queueReadTimeout; } public boolean isTruncateBeforeWriteEnabled() { return truncateBeforeWriteEnabled; } }