2323import java .io .InputStream ;
2424import java .io .InputStreamReader ;
2525import java .util .List ;
26+ import java .util .concurrent .Callable ;
27+ import java .util .concurrent .ExecutorService ;
28+ import java .util .concurrent .Executors ;
29+ import java .util .concurrent .Future ;
2630
31+ import org .neo4j .driver .v1 .util .DaemonThreadFactory ;
2732import org .neo4j .driver .v1 .util .ProcessEnvConfigurator ;
2833
2934import static java .lang .System .lineSeparator ;
3035import static java .util .Arrays .asList ;
36+ import static java .util .concurrent .TimeUnit .MINUTES ;
3137
3238public class CommandLineUtil
3339{
40+ private static final ExecutorService executor = Executors .newCachedThreadPool (
41+ new DaemonThreadFactory ( "command-line-thread-" ) );
42+
3443 public static boolean boltKitAvailable ()
3544 {
3645 try
@@ -59,8 +68,7 @@ public static String executeCommand( List<String> commands )
5968 catch ( InterruptedException e )
6069 {
6170 Thread .currentThread ().interrupt ();
62- throw new CommandLineException ( "Interrupted while waiting for command " +
63- commands , e );
71+ throw new CommandLineException ( "Interrupted while waiting for command " + commands , e );
6472 }
6573 }
6674
@@ -73,17 +81,31 @@ private static String executeAndGetStdOut( ProcessBuilder processBuilder )
7381 throws IOException , InterruptedException
7482 {
7583 Process process = processBuilder .start ();
84+ Future <String > stdOutFuture = read ( process .getInputStream () );
85+ Future <String > stdErrFuture = read ( process .getErrorStream () );
7686 int exitCode = process .waitFor ();
77- String stdOut = asString ( process . getInputStream () );
78- String stdErr = asString ( process . getErrorStream () );
87+ String stdOut = get ( stdOutFuture );
88+ String stdErr = get ( stdErrFuture );
7989 if ( exitCode != 0 )
8090 {
8191 throw new CommandLineException ( "Non-zero exit code\n STDOUT:\n " + stdOut + "\n STDERR:\n " + stdErr );
8292 }
8393 return stdOut ;
8494 }
8595
86- private static String asString ( InputStream input )
96+ private static Future <String > read ( final InputStream input )
97+ {
98+ return executor .submit ( new Callable <String >()
99+ {
100+ @ Override
101+ public String call () throws Exception
102+ {
103+ return readToString ( input );
104+ }
105+ } );
106+ }
107+
108+ private static String readToString ( InputStream input )
87109 {
88110 StringBuilder result = new StringBuilder ();
89111 try ( BufferedReader reader = new BufferedReader ( new InputStreamReader ( input ) ) )
@@ -100,4 +122,16 @@ private static String asString( InputStream input )
100122 }
101123 return result .toString ();
102124 }
125+
126+ private static <T > T get ( Future <T > future )
127+ {
128+ try
129+ {
130+ return future .get ( 10 , MINUTES );
131+ }
132+ catch ( Exception e )
133+ {
134+ throw new RuntimeException ( e );
135+ }
136+ }
103137}
0 commit comments