*/
@Override
public Result parallelise() throws HeraklesException {
if( this.task == null )
throw new HeraklesException( "No task to execute." );
try {
startReasonerThreads( reasoners, this.task );
} catch( NoReasonerException e ) {
throw new HeraklesException( e.getMessage(), e );
}
Result result = null;
Throwable[] exceptions = new Throwable[reasoners.length]; // default init values: null
// will be set to false, while any reasoner is still running
// if no reasoner thread is available this is also a valid statement
boolean allFinished = true;
boolean resultAvailable = false;
if( reasoners != null ) {
boolean[] finished = new boolean[reasoners.length]; // default init values: false
do {
allFinished = true;
for( int j = 0; j < reasoners.length; j++ )
if( reasoners[j].isAlive() )
allFinished = false;
else {
if( reasoners[j].hasFailed() ) {
if( !finished[j] ) {
exceptions[j] = reasoners[j].getException();
if(logger.isWarnEnabled()){
logger.warn( reasoners[j].getName() + " failed: " +
exceptions[j].getMessage() );
}
finished[j] = true;
}
} else {
result = reasoners[j].getResult();
if( result != null )
resultAvailable = true;
finished[j] = true;
if(logger.isInfoEnabled()){
logger.info( reasoners[j].getName() + " finished first (successfully)." );
}
// for time record log to record first finished reasoner
// Herakles.firstReasoner = reasoners[j].getReasoner().getReasonerName();
break;
}
}
} while( !allFinished && !resultAvailable );
}
if( allFinished && !resultAvailable ) {
String message = "All remote reasoners failed:\n";
for( int i = 0; i < reasoners.length; i++ )
if( reasoners[i].getException() != null ) // should always be true, but who knows
message += " " + reasoners[i].getName() + ": " +
reasoners[i].getException().getMessage() + "\n";
throw new HeraklesException( message );
}
return result;
}