-
Notifications
You must be signed in to change notification settings - Fork 55
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
Get process PID, use it to send SIGTERM
#120
base: main
Are you sure you want to change the base?
Conversation
…ly destroying it.
@@ -0,0 +1,48 @@ | |||
package scala.sys.process |
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.
This has to be in the scala.sys.process
package so it has access to Process.SimpleProcess
, which is package private
val method = classOf[JProcess].getMethod("pid") | ||
method.invoke(p) match { | ||
case pid: java.lang.Long => pid | ||
case pid => throw new RuntimeException(s"Expected process PID ($pid) to be a Long, but it was a ${pid.getClass.getName}") | ||
} |
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.
If you're content with requiring everyone who develops sbt-revolver
to use Java 9+ to do so, then this could be simplified to just p.pid
, plus changing the catch
block to handle NoSuchMethodError
when users are on Java 8.
Otherwise, compiling this on Java 8 fails with an error
/Users/matt/sbt-revolver/src/main/scala/scala/sys/process/ProcessWithPid.scala:21:9: value pid is not a member of Process
p.pid
^
|
||
private def killProcess(pid: Long): Unit = { | ||
val exited = try { | ||
JRuntime.getRuntime.exec(s"kill -15 $pid").waitFor(10, TimeUnit.SECONDS) |
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.
Open to suggestions on how long this waits
Fixes #20
Updates
AppProcess
to hold onto aProcessWithPid
, which is a new type defined in thescala.sys.process
package. Given a standardProcess
, theProcessWithPid.apply
method will do its best to get the PID of theProcess
.Unfortunately the only way to do so is via reflection. We first have to reflect on the private
scala.sys.Process.SimpleProcess#p
field to get the underlyingjava.lang.Process
. We then try to call thejava.lang.Process#pid()
method, which exists in Java 9 and above. If that fails with aNoSuchMethodException
, then we fall back to looking at the privatejava.lang.ProcessImpl#pid
field, which works in Java 8 and below.When a PID is discovered,
AppProcess
uses it to send akill -15 <pid>
to the process. It will wait 10 seconds for the process to exit before forcibly killing it withprocess.destroy()
.When we fail to discover a PID for any reason,
AppProcess
will just forcibly kill the process withprocess.destroy()
, as it currently does.