mirror of https://github.com/sbt/sbt.git
refactor: Refactor response handler
**Problem** The sbtn response handling code is relatively stragightforward, but it's a bit messy. **Solution** This cleans it up a bit, similar to the style used by Unfiltered back then (not sure how Unfiltered plans are written nowadays) by expressing each event handling as a partial function, and composing them together using `orElse`.
This commit is contained in:
parent
06acd261d5
commit
a75e847a08
|
|
@ -80,6 +80,13 @@ object Util {
|
||||||
def ignore(f: c.Tree): c.Expr[Unit] = c.universe.reify({ c.Expr[Any](f).splice; () })
|
def ignore(f: c.Tree): c.Expr[Unit] = c.universe.reify({ c.Expr[Any](f).splice; () })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a list of event handlers expressed partial functions, combine them
|
||||||
|
* together using orElse from the left.
|
||||||
|
*/
|
||||||
|
def reduceIntents[A1, A2](intents: PartialFunction[A1, A2]*): PartialFunction[A1, A2] =
|
||||||
|
intents.toList.reduceLeft(_ orElse _)
|
||||||
|
|
||||||
lazy val majorJavaVersion: Int =
|
lazy val majorJavaVersion: Int =
|
||||||
try {
|
try {
|
||||||
val javaVersion = sys.props.get("java.version").getOrElse("1.0")
|
val javaVersion = sys.props.get("java.version").getOrElse("1.0")
|
||||||
|
|
|
||||||
|
|
@ -529,34 +529,42 @@ class NetworkClient(
|
||||||
.getOrElse(1)
|
.getOrElse(1)
|
||||||
case _ => 1
|
case _ => 1
|
||||||
}
|
}
|
||||||
private def completeExec(execId: String, exitCode: => Int): Unit =
|
|
||||||
pendingResults.remove(execId) match {
|
private val onAttachResponse: PartialFunction[JsonRpcResponseMessage, Unit] = {
|
||||||
case null =>
|
case msg if attachUUID.get == msg.id =>
|
||||||
case (q, startTime, name) =>
|
|
||||||
val now = System.currentTimeMillis
|
|
||||||
val message = NetworkClient.timing(startTime, now)
|
|
||||||
val ec = exitCode
|
|
||||||
if (batchMode.get || !attached.get) {
|
|
||||||
if (ec == 0) console.success(message)
|
|
||||||
else console.appendLog(Level.Error, message)
|
|
||||||
}
|
|
||||||
Util.ignoreResult(q.offer(ec))
|
|
||||||
}
|
|
||||||
def onResponse(msg: JsonRpcResponseMessage): Unit = {
|
|
||||||
completeExec(msg.id, getExitCode(msg.result))
|
|
||||||
pendingCancellations.remove(msg.id) match {
|
|
||||||
case null =>
|
|
||||||
case q => q.offer(msg.toString.contains("Task cancelled"))
|
|
||||||
}
|
|
||||||
msg.id match {
|
|
||||||
case execId =>
|
|
||||||
if (attachUUID.get == msg.id) {
|
|
||||||
attachUUID.set(null)
|
attachUUID.set(null)
|
||||||
attached.set(true)
|
attached.set(true)
|
||||||
Option(inputThread.get).foreach(_.drain())
|
Option(inputThread.get).foreach(_.drain())
|
||||||
|
()
|
||||||
}
|
}
|
||||||
pendingCompletions.remove(execId) match {
|
def completeExec(execId: String, exitCode: Int) = {
|
||||||
case null =>
|
pendingResults.remove(execId) match {
|
||||||
|
case null => ()
|
||||||
|
case (q, startTime, name) =>
|
||||||
|
val now = System.currentTimeMillis
|
||||||
|
val message = NetworkClient.timing(startTime, now)
|
||||||
|
if (batchMode.get || !attached.get) {
|
||||||
|
if (exitCode == 0) console.success(message)
|
||||||
|
else console.appendLog(Level.Error, message)
|
||||||
|
}
|
||||||
|
Util.ignoreResult(q.offer(exitCode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val onExecResponse: PartialFunction[JsonRpcResponseMessage, Unit] = {
|
||||||
|
case msg if pendingResults.containsKey(msg.id) =>
|
||||||
|
completeExec(msg.id, getExitCode(msg.result))
|
||||||
|
}
|
||||||
|
private val onCancellationResponse: PartialFunction[JsonRpcResponseMessage, Unit] = {
|
||||||
|
case msg if pendingCancellations.containsKey(msg.id) =>
|
||||||
|
pendingCancellations.remove(msg.id) match {
|
||||||
|
case null => ()
|
||||||
|
case q => Util.ignoreResult(q.offer(msg.toString.contains("Task cancelled")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val onCompletionResponse: PartialFunction[JsonRpcResponseMessage, Unit] = {
|
||||||
|
case msg if pendingCompletions.containsKey(msg.id) =>
|
||||||
|
pendingCompletions.remove(msg.id) match {
|
||||||
|
case null => ()
|
||||||
case completions =>
|
case completions =>
|
||||||
completions(msg.result match {
|
completions(msg.result match {
|
||||||
case Some(o: JObject) =>
|
case Some(o: JObject) =>
|
||||||
|
|
@ -583,7 +591,15 @@ class NetworkClient(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// cache the composed plan
|
||||||
|
private val responsePlan = Util.reduceIntents[JsonRpcResponseMessage, Unit](
|
||||||
|
onExecResponse,
|
||||||
|
onCancellationResponse,
|
||||||
|
onAttachResponse,
|
||||||
|
onCompletionResponse,
|
||||||
|
{ case _ => () },
|
||||||
|
)
|
||||||
|
def onResponse(msg: JsonRpcResponseMessage): Unit = responsePlan(msg)
|
||||||
|
|
||||||
def onNotification(msg: JsonRpcNotificationMessage): Unit = {
|
def onNotification(msg: JsonRpcNotificationMessage): Unit = {
|
||||||
def splitToMessage: Vector[(Level.Value, String)] =
|
def splitToMessage: Vector[(Level.Value, String)] =
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue