private List < FutureHolder < ? > > waitForFutures ( final Queue < ? extends FutureHolder < ? > > futures , final PrintWriter reportWriter , final File reportDirectory , final boolean wait ) throws InterruptedException { final List < FutureHolder < ? > > failedFutures = new LinkedList <> ( ) ; for ( Iterator < ? extends FutureHolder < ? > > futuresItr = futures . iterator ( ) ; futuresItr . hasNext ( ) ; ) { final FutureHolder < ? > futureHolder = futuresItr . next ( ) ; // If waiting, or if not waiting but the future is already done do the get final Future < ? > future = futureHolder . getFuture ( ) ; if ( wait || ( ! wait && future . isDone ( ) ) ) { futuresItr . remove ( ) ; try { // Don't bother doing a get() on canceled futures if ( ! future . isCancelled ( ) ) { if ( this . maxWait > 0 ) { future . get ( this . maxWait , this . maxWaitTimeUnit ) ; } else { future . get ( ) ; } reportWriter . printf ( REPORT_FORMAT , "SUCCESS" , futureHolder . getDescription ( ) , futureHolder . getExecutionTimeMillis ( ) ) ; } } catch ( CancellationException e ) { // Ignore cancellation exceptions } catch ( ExecutionException e ) { logger . error ( "Failed: " + futureHolder ) ; futureHolder . setError ( e ) ; failedFutures . add ( futureHolder ) ; reportWriter . printf ( REPORT_FORMAT , "FAIL" , futureHolder . getDescription ( ) , futureHolder . getExecutionTimeMillis ( ) ) ; try { final String dataReportName = SafeFilenameUtils . makeSafeFilename ( futureHolder . getDataType ( ) + "_" + futureHolder . getDataName ( ) + ".txt" ) ; final File dataReportFile = new File ( reportDirectory , dataReportName ) ; final PrintWriter dataReportWriter = new PrintWriter ( new BufferedWriter ( new FileWriter ( dataReportFile ) ) ) ; try { dataReportWriter . println ( "FAIL: " + futureHolder . getDataType ( ) + " - " + futureHolder . getDataName ( ) ) ; dataReportWriter . println ( "--------------------------------------------------------------------------------" ) ; e . getCause ( ) . printStackTrace ( dataReportWriter ) ; } finally { IOUtils . closeQuietly ( dataReportWriter ) ; } } catch ( Exception re ) { logger . warn ( "Failed to write error report for failed " + futureHolder + ", logging root failure here" , e . getCause ( ) ) ; } } catch ( TimeoutException e ) { logger . warn ( "Failed: " + futureHolder ) ; futureHolder . setError ( e ) ; failedFutures . add ( futureHolder ) ; future . cancel ( true ) ; reportWriter . printf ( REPORT_FORMAT , "TIMEOUT" , futureHolder . getDescription ( ) , futureHolder . getExecutionTimeMillis ( ) ) ; } } } return failedFutures ; }
Used by batch import and export to wait for queued tasks to complete . Handles fail - fast behavior if any of the tasks threw and exception by canceling all queued futures and logging a summary of the failures . All completed futures are removed from the queue .