package de.axone.async;
import java.io.IOException;
import java.util.LinkedList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.axone.exception.codify.Codifier;
public abstract class AsynchronousQueue<T> extends Thread {
protected final Logger log;
private volatile boolean pleaseStop = false;
protected LinkedList<T> queue = new LinkedList<T>();
private int inProcess = 0;
public AsynchronousQueue( String threadName ){
super( threadName );
log = LoggerFactory.getLogger( this.getClass() );
}
public void push( T data ){
synchronized( queue ){
queue.addLast( data );
queue.notifyAll();
}
}
private T pop(){
T data = null;
synchronized( queue ) {
if( queue.size() > 0 ) {
data = queue.removeFirst();
inProcess = 1;
}
}
return data;
}
private void sleep(){
log.trace( "gotoSleep" );
synchronized( queue ) {
try {
while( !pleaseStop && queue.size() == 0 ){
queue.wait();
}
} catch( InterruptedException e ) {}
}
log.trace( "woke up" );
}
protected abstract String info( T data );
protected abstract void process( T data ) throws Exception;
@Override
public void run() {
log.debug( "STARTING" );
do {
T data = pop();
if( data != null ) {
if( log.isTraceEnabled() ) log.trace( "Processing: " + info( data ) );
try {
process( data );
synchronized( queue ){ inProcess=0; }
if( log.isTraceEnabled() ){
log.trace( "done: " + info( data ) );
log.trace( "remaining:" + size() );
}
} catch( Exception e ){
log.error( "Error processing: " + info( data ), e );
try {
Codifier.report( e );
} catch( IOException e1 ) {
log.error( "Cannot report", e );
}
}
}
sleep();
} while( !pleaseStop );
log.debug( "FINISHED" );
}
public void pleaseStop(){
pleaseStop = true;
synchronized( queue ) {
queue.notifyAll();
}
}
public int size(){
synchronized( queue ){
return queue.size() + inProcess;
}
}
}