Skip to content

Commit

Permalink
Refactored JGrabDaemon.
Browse files Browse the repository at this point in the history
  • Loading branch information
renatoathaydes committed Apr 29, 2024
1 parent 7f0506d commit 9866624
Showing 1 changed file with 101 additions and 79 deletions.
180 changes: 101 additions & 79 deletions jgrab-runner/src/main/java/com/athaydes/jgrab/daemon/JGrabDaemon.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
/**
* JGrab daemon, a TCP socket server that runs in the background waiting for Java code to run.
*/
public class JGrabDaemon {
public final class JGrabDaemon {

private static final Logger logger = LoggerFactory.getLogger( JGrabDaemon.class );
private static final String STOP_OPTION = "--stop";
Expand All @@ -42,6 +42,7 @@ public class JGrabDaemon {
} ) );
}

@SuppressWarnings( "resource" )
public static void start( RunArgs runArgs ) {
new Thread( () -> {
logger.debug( "Starting JGrab Daemon" );
Expand All @@ -60,94 +61,115 @@ public static void start( RunArgs runArgs ) {
final PrintStream out = new PrintStream( clientSocket.getOutputStream(), true );
BufferedReader in = new BufferedReader(
new InputStreamReader( clientSocket.getInputStream() ) ) ) {
String firstLine = null;
String inputLine;
StringBuilder messageBuilder = new StringBuilder( 1024 );

while ( ( inputLine = in.readLine() ) != null ) {
if ( firstLine == null ) {
firstLine = inputLine;
} else {
messageBuilder.append( inputLine ).append( '\n' );
}
}

if ( firstLine == null ) {
out.println( "Communication error (input line is null)" );
continue;
}

JavaCode code;
String[] args;

// check for Java file contents preceded by Java arguments
if ( messageBuilder.length() > 0 && JAVA_ARGUMENTS_LINE.matcher( firstLine ).matches() ) {
// remove the [] demarkers
String javaArgs = firstLine.substring( 1, firstLine.length() - 1 );
logger.debug( "Java arguments: {}", javaArgs );
code = new StringJavaCode( messageBuilder.toString() );
args = javaArgs.split( " " );
} else {
String input = ( firstLine + "\n" + messageBuilder ).trim();

if ( input.equals( STOP_OPTION ) ) {
logger.info( "--stop option received, stopping JGrab Daemon" );
out.println( "=== JGrab Daemon stopped ===" );
return;
}

if ( input.equals( VERSION_OPTION ) ) {
logger.info( "--version option received" );
System.setOut( out );
System.setErr( out );
JGrabRunner.printVersion();
continue;
}

if ( input.startsWith( JGrabOptions.SNIPPET_OPTION ) ) {
String snippet = input.substring( JGrabOptions.SNIPPET_OPTION.length() );
if ( snippet.isEmpty() ) {
out.println( "ERROR: no snippet provided to execute" );
continue;
} else {
code = new StringJavaCode( snippet );
args = new String[ 0 ];
}
} else {
code = new StringJavaCode( input );
args = new String[ 0 ];
}
}

logSourceCode( code );

var deps = code.extractDependencies();

logger.debug( "Dependencies to grab: {}", deps );

var classpath = libsCache.classpathOf( deps, () -> grabber.grab( deps ) );

System.setIn( clientSocket.getInputStream() );
System.setOut( out );
System.setErr( out );

// run this synchronously, which means only one program can run per daemon at a time
try {
runArgs.accept( code, args, classpath );
} catch ( Throwable t ) {
t.printStackTrace( out );
}
handleClient( in, out, runArgs );
} catch ( IOException e ) {
logger.warn( "Problem handling client message", e );
} finally {
System.setIn( System.in );
System.setOut( System.out );
System.setErr( System.err );
}
}
}, "jgrab-daemon" ).start();
}

private static void handleClient(
BufferedReader in,
PrintStream out,
RunArgs runArgs ) throws IOException {
var request = parseRequest( in, out );
if ( request == null ) return;

logSourceCode( request.code );

var deps = request.code.extractDependencies();

logger.debug( "Dependencies to grab: {}", deps );

var classpath = libsCache.classpathOf( deps, () -> grabber.grab( deps ) );

System.setOut( out );
System.setErr( out );

// run this synchronously, which means only one program can run per daemon at a time
try {
runArgs.accept( request.code, request.args, classpath );
} catch ( Throwable t ) {
t.printStackTrace( out );
}
}

private static CodeRunRequest parseRequest( BufferedReader in, PrintStream out ) throws IOException {
String firstLine = null;
String inputLine;
StringBuilder messageBuilder = new StringBuilder( 1024 );

while ( ( inputLine = in.readLine() ) != null ) {
if ( firstLine == null ) {
firstLine = inputLine;
} else {
messageBuilder.append( inputLine ).append( '\n' );
}
}

if ( firstLine == null ) {
out.println( "Communication error (input line is null)" );
return null;
}

JavaCode code;
String[] args;

// check for Java file contents preceded by Java arguments
if ( messageBuilder.length() > 0 && JAVA_ARGUMENTS_LINE.matcher( firstLine ).matches() ) {
// remove the [] demarkers
String javaArgs = firstLine.substring( 1, firstLine.length() - 1 );
logger.debug( "Java arguments: {}", javaArgs );
code = new StringJavaCode( messageBuilder.toString() );
args = javaArgs.split( " " );
} else {
String input = ( firstLine + "\n" + messageBuilder ).trim();

if ( input.equals( STOP_OPTION ) ) {
logger.info( "--stop option received, stopping JGrab Daemon" );
out.println( "=== JGrab Daemon stopped ===" );
return null;
}

if ( input.equals( VERSION_OPTION ) ) {
logger.info( "--version option received" );
System.setOut( out );
System.setErr( out );
JGrabRunner.printVersion();
return null;
}

if ( input.startsWith( JGrabOptions.SNIPPET_OPTION ) ) {
String snippet = input.substring( JGrabOptions.SNIPPET_OPTION.length() );
if ( snippet.isEmpty() ) {
out.println( "ERROR: no snippet provided to execute" );
return null;
} else {
code = new StringJavaCode( snippet );
args = new String[ 0 ];
}
} else {
code = new StringJavaCode( input );
args = new String[ 0 ];
}
}
return new CodeRunRequest( code, args );
}

private static final class CodeRunRequest {
public final JavaCode code;
public final String[] args;

public CodeRunRequest( JavaCode code, String[] args ) {
this.code = code;
this.args = args;
}
}

private static void logSourceCode( Object source ) {
logger.trace( "Source code:\n------------------------------------\n" +
"{}\n------------------------------------\n", source );
Expand Down

0 comments on commit 9866624

Please sign in to comment.