@@ -117,12 +117,18 @@ abstract class WorkerMain[S](stdin: InputStream = System.in, stdout: PrintStream
117117 // close them after the async work in the Future is all done.
118118 // If we do something synchronous with Using, then there's a race condition where the
119119 // streams can get closed before the Future is completed.
120- var outStream : ByteArrayOutputStream = null
121- var out : PrintStream = null
120+ var maybeOutStream : Option [ByteArrayOutputStream ] = None
121+ var maybeOut : Option [PrintStream ] = None
122+
123+ def flushOut (): Unit = {
124+ maybeOut.map(_.flush())
125+ }
122126
123127 val workTask = CancellableTask {
124- outStream = new ByteArrayOutputStream
125- out = new PrintStream (outStream)
128+ val outStream = new ByteArrayOutputStream ()
129+ val out = new PrintStream (outStream)
130+ maybeOutStream = Some (outStream)
131+ maybeOut = Some (out)
126132 try {
127133 work(ctx, args, out, sandboxDir, verbosity)
128134 0
@@ -137,24 +143,25 @@ abstract class WorkerMain[S](stdin: InputStream = System.in, stdout: PrintStream
137143 .andThen {
138144 // Work task succeeded or failed in an expected way
139145 case Success (code) =>
140- out.flush ()
141- writeResponse(requestId, Some (outStream) , Some (code))
146+ flushOut ()
147+ writeResponse(requestId, maybeOutStream , Some (code))
142148 logVerbose(s " WorkResponse $requestId sent with code $code" )
143149
144150 case Failure (e : ExecutionException ) =>
145151 e.getCause() match {
146152 // Task successfully cancelled
147153 case cancelError : InterruptedException =>
154+ flushOut()
148155 writeResponse(requestId, None , None , wasCancelled = true )
149156 logVerbose(
150157 s " Cancellation WorkResponse sent for request id: $requestId in response to an " +
151158 " InterruptedException" ,
152159 )
153160 // Work task threw a non-fatal error
154161 case e =>
155- e.printStackTrace(out )
156- out.flush ()
157- writeResponse(requestId, Some (outStream) , Some (- 1 ))
162+ maybeOut.map( e.printStackTrace(_) )
163+ flushOut ()
164+ writeResponse(requestId, maybeOutStream , Some (- 1 ))
158165 logVerbose(
159166 " Encountered an uncaught exception that was wrapped in an ExecutionException while" +
160167 s " proccessing the Future for WorkRequest $requestId. This usually means a non-fatal " +
@@ -165,6 +172,7 @@ abstract class WorkerMain[S](stdin: InputStream = System.in, stdout: PrintStream
165172
166173 // Task successfully cancelled
167174 case Failure (e : CancellationException ) =>
175+ flushOut()
168176 writeResponse(requestId, None , None , wasCancelled = true )
169177 logVerbose(
170178 s " Cancellation WorkResponse sent for request id: $requestId in response to a " +
@@ -173,15 +181,15 @@ abstract class WorkerMain[S](stdin: InputStream = System.in, stdout: PrintStream
173181
174182 // Work task threw an uncaught exception
175183 case Failure (e) =>
176- e.printStackTrace(out )
177- out.flush ()
178- writeResponse(requestId, Some (outStream) , Some (- 1 ))
184+ maybeOut.map( e.printStackTrace(_) )
185+ flushOut ()
186+ writeResponse(requestId, maybeOutStream , Some (- 1 ))
179187 logVerbose(s " Uncaught exception in Future while proccessing WorkRequest $requestId: " )
180188 e.printStackTrace(System .err)
181189 }(scala.concurrent.ExecutionContext .global)
182190 .andThen { case _ =>
183- out. close()
184- outStream. close()
191+ maybeOut.map(_. close() )
192+ maybeOutStream.map(_. close() )
185193 }(scala.concurrent.ExecutionContext .global)
186194
187195 // putIfAbsent will return a non-null value if there was already a value in the map
0 commit comments