From e94746e8fdc782953a8e2f177218b4e5b181827e Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Tue, 21 Feb 2017 22:34:45 +1100 Subject: [PATCH] build Callable first before invoke fix #8 Signed-off-by: olivier lamy --- .../jetty/load/generator/LoadGenerator.java | 9 ++++- .../load/generator/LoadGeneratorRunner.java | 40 +++++++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGenerator.java b/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGenerator.java index 12d67814..f2a9cd1a 100644 --- a/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGenerator.java +++ b/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGenerator.java @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -408,7 +409,9 @@ public void run( int transactionNumber ) { HttpClientTransport httpClientTransport = getHttpClientTransport(); - List> futures = new ArrayList>( getUsers() ); + + + List> callables = new ArrayList<>( getUsers() ); for ( int i = getUsers(); i > 0; i-- ) { @@ -427,7 +430,7 @@ public void run( int transactionNumber ) new LoadGeneratorRunner( httpClient, this, _loadGeneratorResultHandler, // transactionNumber); - futures.add( this.runnersExecutorService.submit( loadGeneratorRunner )); + callables.add( loadGeneratorRunner ); } catch ( Throwable e ) @@ -437,6 +440,8 @@ public void run( int transactionNumber ) } } + List> futures = this.runnersExecutorService.invokeAll( callables ); + while ( !LoadGenerator.this.stop.get() && !futures.stream().allMatch( future -> future.isDone() )) { // wait until stopped diff --git a/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGeneratorRunner.java b/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGeneratorRunner.java index 0e44e9a0..c69dc979 100644 --- a/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGeneratorRunner.java +++ b/jetty-load-generator-client/src/main/java/org/mortbay/jetty/load/generator/LoadGeneratorRunner.java @@ -29,16 +29,19 @@ import org.mortbay.jetty.load.generator.profile.Resource; import java.net.HttpCookie; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * */ public class LoadGeneratorRunner - implements Runnable + implements Callable { private static final Logger LOGGER = Log.getLogger( LoadGeneratorRunner.class ); @@ -67,8 +70,9 @@ public LoadGeneratorRunner( HttpClient httpClient, LoadGenerator loadGenerator, this.transactionNumber = transactionNumber; } + @Override - public void run() + public Void call() { LOGGER.debug( "loadGenerator#run" ); try @@ -118,6 +122,7 @@ public void run() LOGGER.warn( "ignoring exception:" + e.getMessage(), e ); // TODO record error in generator report } + return null; } private void handleResource( Resource resource ) @@ -139,25 +144,28 @@ private void handleResource( Resource resource ) // it's a group so we can request in parallel but wait all responses before next step ExecutorService executorService = Executors.newWorkStealingPool(); + List> callables = new ArrayList<>( resource.getResources().size() ); + + for ( Resource children : resource.getResources() ) { - executorService.execute( () -> - { - try - { - handleResource( children ); - } - catch ( Exception e ) - { - LOGGER.debug( e.getMessage(), e ); - } - } ); + callables.add( () -> + { + try + { + handleResource( children ); + } + catch ( Exception e ) + { + LOGGER.debug( e.getMessage(), e ); + } + return null; + } ); } - executorService.shutdown(); + List> futures = executorService.invokeAll( callables, resource.getChildrenTimeout(), TimeUnit.MILLISECONDS ); + boolean finished = futures.stream().allMatch( voidFuture -> voidFuture.isDone() ); - // TODO make this configurable?? - boolean finished = executorService.awaitTermination( resource.getChildrenTimeout(), TimeUnit.MILLISECONDS ); if ( !finished ) { LOGGER.warn( "resourceGroup request not all completed for timeout " + resource.getChildrenTimeout() );