@@ -62,6 +62,7 @@ public class Service implements AutoCloseable {
62
62
private PrintWriter stdin ;
63
63
private Thread stdoutThread ;
64
64
private Thread stderrThread ;
65
+ private Thread monitorThread ;
65
66
66
67
private Consumer <String > debugListener ;
67
68
@@ -99,8 +100,10 @@ public Service start() throws IOException {
99
100
stdin = new PrintWriter (process .getOutputStream ());
100
101
stdoutThread = new Thread (this ::stdoutLoop , prefix + "-Stdout" );
101
102
stderrThread = new Thread (this ::stderrLoop , prefix + "-Stderr" );
103
+ monitorThread = new Thread (this ::monitorLoop , prefix + "-Monitor" );
102
104
stderrThread .start ();
103
105
stdoutThread .start ();
106
+ monitorThread .start ();
104
107
return this ;
105
108
}
106
109
@@ -194,6 +197,35 @@ private void stderrLoop() {
194
197
}
195
198
}
196
199
200
+ private void monitorLoop () {
201
+ // Wait until the worker process terminates.
202
+ while (process .isAlive ()) {
203
+ try {
204
+ Thread .sleep (50 );
205
+ }
206
+ catch (InterruptedException exc ) {
207
+ debugService (Types .stackTrace (exc ));
208
+ }
209
+ }
210
+
211
+ // Do some sanity checks.
212
+ int exitCode = process .exitValue ();
213
+ if (exitCode != 0 ) debugService ("<worker process terminated with exit code " + exitCode + ">" );
214
+ int taskCount = tasks .size ();
215
+ if (taskCount > 0 ) debugService ("<worker process terminated with " + taskCount + " pending tasks>" );
216
+
217
+ // Notify any remaining tasks about the process crash.
218
+ for (Task task : tasks .values ()) {
219
+ TaskEvent event = new TaskEvent (task , ResponseType .CRASH );
220
+ task .status = TaskStatus .CRASHED ;
221
+ task .listeners .forEach (l -> l .accept (event ));
222
+ synchronized (task ) {
223
+ task .notifyAll ();
224
+ }
225
+ }
226
+ tasks .clear ();
227
+ }
228
+
197
229
private void debugService (String message ) { debug ("SERVICE" , message ); }
198
230
private void debugWorker (String message ) { debug ("WORKER" , message ); }
199
231
@@ -207,13 +239,13 @@ private void debug(String prefix, String message) {
207
239
}
208
240
209
241
public enum TaskStatus {
210
- INITIAL , QUEUED , RUNNING , COMPLETE , CANCELED , FAILED ;
242
+ INITIAL , QUEUED , RUNNING , COMPLETE , CANCELED , FAILED , CRASHED ;
211
243
212
244
/**
213
- * @return true iff status is {@link #COMPLETE}, {@link #CANCELED}, or {@link #FAILED }.
245
+ * @return true iff status is {@link #COMPLETE}, {@link #CANCELED}, {@link #FAILED}, or {@link #CRASHED }.
214
246
*/
215
247
public boolean isFinished () {
216
- return this == COMPLETE || this == CANCELED || this == FAILED ;
248
+ return this == COMPLETE || this == CANCELED || this == FAILED || this == CRASHED ;
217
249
}
218
250
}
219
251
@@ -222,7 +254,7 @@ public enum RequestType {
222
254
}
223
255
224
256
public enum ResponseType {
225
- LAUNCH , UPDATE , COMPLETION , CANCELATION , FAILURE
257
+ LAUNCH , UPDATE , COMPLETION , CANCELATION , FAILURE , CRASH
226
258
}
227
259
228
260
/**
0 commit comments