kobalt
kobalt copied to clipboard
"run" task blocks 30 seconds (and fails) if running application output is large
When I run an application, which outputs several kilobytes to System.out, with the run task, Kobalt blocks for 30 seconds and then fails.
The problem seems that Kobalt does not read the output of the running application while waiting for its exit. So the output buffer becomes full and the running app blocks.
From java.lang.Process javadoc:
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock
The current implementation in class RunCommand is
val callSucceeded = process.waitFor(30, TimeUnit.SECONDS)
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream) else emptyList()
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream) else emptyList()
So it seems to be necessary to start two threads that read process.inputStream and process.errorStream before invoking process.waitFor().
The timeout of only 30 seconds seems to be very low. What if a app needs more time to run?
Better change it to e.g. 5 minutes and/or make it configurable in the application directive.
Yes, that would be better. Are you interested in sending a pull request?
Cédric
On Wed, Jul 6, 2016 at 2:53 AM, DevCharly [email protected] wrote:
When I run an application, which outputs several kilobytes to System.out, with the run task, Kobalt blocks for 30 seconds and then fails.
The problem seems that Kobalt does not read the output of the running application while waiting for its exit. So the output buffer becomes full and the running app blocks.
From java.lang.Process javadoc:
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock
The current implementation in class RunCommand is
val callSucceeded = process.waitFor(30, TimeUnit.SECONDS) val input = if (process.inputStream.available() > 0) fromStream(process.inputStream) else emptyList() val error = if (process.errorStream.available() > 0) fromStream(process.errorStream) else emptyList()So it seems to be necessary to start two threads that read process.inputStream and process.errorStream before invoking process.waitFor().
The timeout of only 30 seconds seems to be very low. What if a app needs more time to run? Better change it to e.g. 5 minutes and/or make it configurable in the application directive.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/cbeust/kobalt/issues/259, or mute the thread https://github.com/notifications/unsubscribe/AAFooqAAnDffX3O_ZgJ1fi1TyklQBBV7ks5qS3sAgaJpZM4JF7D4 .
Yes, I'll send a PR...
Feel free to use KobaltExecutors.miscExecutor for this (or you can create your own, but I think using misc is fine here).