-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a non-blocking process implementation #60
Conversation
@ktoso ... in case you're interested in reviewing further :-) @longshorej ... in case you're interested integrating with our code base - we'll need to cherry pick changes to an Akka 2.4 flavour of this lib though (shouldn't be hard). |
Branch created @ https://github.com/typesafehub/akka-contrib-extra/tree/3.0, I'll backport this PR once merged. |
* @param stderr a `akka.stream.scaladsl.Source[ByteString]` for the standard error stream of the process | ||
*/ | ||
case class Started( | ||
pid: Long, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think pid: Int
-- NuProcess.getPID()
returns an int
On second thought, ignore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was influenced here by the forthcoming JDK process API (which we'll probably never use!)
d49f01d
to
7d16a09
Compare
Hey, @viktorklang - would you care to review - I think this PR would be right up your alley. :-) |
0b6eb29
to
31d9460
Compare
Tests are failing fairly consistently on Travis with:
I don't seem to be able to reproduce this locally. I've enhanced the test build config to cut out parallelism etc. but still no cigar... |
Update on #60 (comment) I can reproduce this problem with reasonable consistency on Linux - harder to reproduce when invoking the |
@longshorej I've disabled that test you added a while back in the interest of pushing this forward. Would you mind re-visiting that test? It isn't making much sense to me. For starters, the test declares, "detect when a process has exited of its own accord", but it isn't - a |
@longshorej I’ve re-instated that test of yours for |
*/ | ||
class NonBlockingProcess( | ||
command: immutable.Seq[String], | ||
directory: File, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we take a Path
instead and thus fully be using java.nio
for everything?
} | ||
val isRunning = process.isRunning match { | ||
case true if hasProcDir => procDirAlive(process.getPID)(contextMat, implicitly) | ||
case result => Future.successful(result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We weren't handling non-Linux scenarios. :-)
@@ -20,36 +21,37 @@ class BlockingProcessSpec extends WordSpec with Matchers with BeforeAndAfterAll | |||
|
|||
implicit val system = ActorSystem("test", testConfig) | |||
|
|||
implicit val processCreationTimeout = Timeout(2.seconds) | |||
implicit val processCreationTimeout = Timeout(2.seconds.dilated) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case we ever declare a test timeout factor
val stdinInput = List("abcd", "1234", "quit") | ||
val receiver = system.actorOf(Props(new Receiver(probe.ref, command, stdinInput, 1)), "receiver1") | ||
val receiver = system.actorOf(Props(new Receiver(streamProbe.ref, exitProbe.ref, command, stdinInput, 1)), "receiver1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduced the distinction between stream and exit probes as it is technically possible to get an exit prior to the stream data
@@ -20,36 +21,37 @@ class BlockingProcessSpec extends WordSpec with Matchers with BeforeAndAfterAll | |||
|
|||
implicit val system = ActorSystem("test", testConfig) | |||
|
|||
implicit val processCreationTimeout = Timeout(2.seconds) | |||
implicit val processCreationTimeout = Timeout(2.seconds.dilated) | |||
|
|||
"A BlockingProcess" should { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some small fixes to the blocking tests here.
case NonBlockingProcess.Exited(255) => true | ||
case _ => false | ||
case NonBlockingProcess.Exited(_) => true | ||
case _ => false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of non-Linux - we can get any non zero code.
process ! NonBlockingProcess.Destroy | ||
|
||
exitProbe.fishForMessage() { | ||
case NonBlockingProcess.Exited(s) if s != 0 => true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of non-proc checking, we can get any non-zero
Utilises NuProcess in order to provide a non-blocking process implementation for Windows, OS X and Linux. We've also modified some of the blocking tests in order to improve their robustness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Utilises NuProcess in order to provide a non-blocking process implementation for Windows, OS X and Linux.
Authors: @longshorej and @huntc