mirror of https://github.com/sbt/sbt.git
Add remote cancellation support
This commit makes it possible for a remote client to cancel a running task initiated by a different client by typing `cancel` into the shell. It can be useful if the remote client has run something blocking like console. The console task can't safely be interrupted, so instead we write some newlines filed by ctrl+d to exit the console.
This commit is contained in:
parent
ba345dd797
commit
ab362397ba
|
|
@ -658,6 +658,7 @@ private[sbt] object ProgressState {
|
|||
}
|
||||
} else {
|
||||
pe.command.toSeq.flatMap { cmd =>
|
||||
val tail = if (isWatch) Nil else "enter 'cancel' to stop evaluation" :: Nil
|
||||
s"sbt server is running '$cmd'" :: tail
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,6 +350,15 @@ private[sbt] final class CommandExchange {
|
|||
commandQueue.add(exit)
|
||||
()
|
||||
}
|
||||
private[this] def cancel(e: Exec): Unit = {
|
||||
if (e.commandLine.startsWith("console")) {
|
||||
val terminal = Terminal.get
|
||||
terminal.write(13, 13, 13, 4)
|
||||
terminal.printStream.println("\nconsole session killed by remote sbt client")
|
||||
} else {
|
||||
Util.ignoreResult(NetworkChannel.cancel(e.execId, e.execId.getOrElse("0")))
|
||||
}
|
||||
}
|
||||
|
||||
private[this] class MaintenanceThread
|
||||
extends Thread("sbt-command-exchange-maintenance")
|
||||
|
|
|
|||
|
|
@ -698,6 +698,40 @@ object NetworkChannel {
|
|||
case object SingleLine extends ChannelState
|
||||
case object InHeader extends ChannelState
|
||||
case object InBody extends ChannelState
|
||||
private[sbt] def cancel(
|
||||
execID: Option[String],
|
||||
id: String
|
||||
): Either[String, String] = {
|
||||
|
||||
Option(EvaluateTask.currentlyRunningEngine.get) match {
|
||||
case Some((state, runningEngine)) =>
|
||||
val runningExecId = state.currentExecId.getOrElse("")
|
||||
|
||||
def checkId(): Boolean = {
|
||||
if (runningExecId.startsWith("\u2668")) {
|
||||
(
|
||||
Try { id.toLong }.toOption,
|
||||
Try { runningExecId.substring(1).toLong }.toOption
|
||||
) match {
|
||||
case (Some(id), Some(eid)) => id == eid
|
||||
case _ => false
|
||||
}
|
||||
} else runningExecId == id
|
||||
}
|
||||
|
||||
// direct comparison on strings and
|
||||
// remove hotspring unicode added character for numbers
|
||||
if (checkId) {
|
||||
runningEngine.cancelAndShutdown()
|
||||
Right(runningExecId)
|
||||
} else {
|
||||
Left("Task ID not matched")
|
||||
}
|
||||
|
||||
case None =>
|
||||
Left("No tasks under execution")
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] val disconnect: Command =
|
||||
Command.arb { s =>
|
||||
|
|
|
|||
Loading…
Reference in New Issue