package com.grendelscan.queues; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.grendelscan.scan.InterruptedScanException; public abstract class AbstractQueueThread implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractQueueThread.class); private static final long THREAD_SLEEP_TIME = 250; private boolean lastWorkItem = false; private Thread thread; protected QueueThreadState threadState; protected AbstractQueueThread(QueueThreadGroup threadGroup) { threadState = QueueThreadState.CREATING; thread = new Thread(threadGroup, this, getQueue().getName() + " thread"); } protected abstract AbstractScanQueue getQueue(); protected abstract void processNextItem(QueueItem nextItem) throws InterruptedScanException; @Override public void run() { while (!lastWorkItem) { try { handlePause_isRunning(); threadState = QueueThreadState.POLLING; QueueItem nextItem = getQueue().getNextQueueItem(); handlePause_isRunning(); if ((nextItem != null)) { threadState = QueueThreadState.PROCESSING; processNextItem(nextItem); getQueue().removeQueueItem(nextItem); handlePause_isRunning(); } else { threadState = QueueThreadState.SLEEPING; aLittleSleep(); } } catch (InterruptedScanException e) { LOGGER.debug(getName() + " interrupted" + e.toString(), e); threadState = QueueThreadState.TERMINATING; return; } catch (Exception e) { LOGGER.error("Uncaught exception in " + getName() + " thread: " + e.toString(), e); } } threadState = QueueThreadState.TERMINATING; } /** * This will properly interrupt the thread and tell it to process no other tasks. * It does not currently have the ability to abort a task already started. */ public void interupt() { thread.interrupt(); } protected void handlePause_isRunning() throws InterruptedScanException { getQueue().handlePause_isRunning(); } public void start() { thread.start(); } public String getName() { return thread.getName(); } public QueueThreadState getThreadState() { return threadState; } private void aLittleSleep() throws InterruptedScanException { try { Thread.sleep(THREAD_SLEEP_TIME); } catch (InterruptedException e) { throw new InterruptedScanException("Scan interupted", e); } } // protected void checkPause() // { // if (getQueue().isPaused()) // { // QueueThreadState oldState = threadState; // threadState = QueueThreadState.PAUSED; // while (getQueue().isPaused()) // { // aLittleSleep(); // } // threadState = oldState; // } // } final protected boolean isLastWorkItem() { return lastWorkItem; } public final boolean isAlive() { return thread.isAlive(); } public final void setLastWorkItem(boolean lastWorkItem) { this.lastWorkItem = lastWorkItem; } }