From 73f86a68a885018aff9e68ff6f2718a7f580fb40 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Mon, 19 Feb 2024 12:51:57 +0100 Subject: [PATCH 1/4] Make BSP task processing more resilient --- .../src/mill/bsp/worker/MillBuildServer.scala | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 234697c86cf..5b2b67f4987 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -26,6 +26,8 @@ import ch.epfl.scala.bsp4j.{ InitializeBuildResult, InverseSourcesParams, InverseSourcesResult, + LogMessageParams, + MessageType, OutputPathItem, OutputPathItemKind, OutputPathsItem, @@ -75,9 +77,10 @@ import scala.reflect.ClassTag import scala.util.{Failure, Success, Try} import Utils.sanitizeUri import mill.bsp.BspServerResult -import mill.eval.Evaluator.TaskResult +import mill.eval.Evaluator.{Results, TaskResult} import scala.util.chaining.scalaUtilChainingOps +import scala.util.control.NonFatal private class MillBuildServer( bspVersion: String, serverVersion: String, @@ -649,7 +652,8 @@ private class MillBuildServer( targetIds: State => Seq[BuildTargetIdentifier], tasks: BspModule => Task[W] )(f: (Evaluator, State, BuildTargetIdentifier, BspModule, W) => T)(agg: java.util.List[T] => V) - : CompletableFuture[V] = + : CompletableFuture[V] = { + val prefix = hint.split(" ").head completable(hint) { state: State => val ids = targetIds(state) val tasksSeq = ids.map { id => @@ -658,14 +662,40 @@ private class MillBuildServer( } val evaluated = tasksSeq + // group by evaluator (different root module) .groupMap(_._2)(_._1) .map { case ((ev, id), ts) => - ev.evalOrThrow()(ts) - .map { v => f(ev, state, id, state.bspModulesById(id)._1, v) } + val results = ev.evaluate(ts) + val failures = results.results.collect { + case (_, TaskResult(res: Result.Failing[_], _)) => res + } + + if (failures.nonEmpty) { + // somehow report failures to the build client + val msg = s"Request '$prefix' failed for ${id.getUri}: ${failures.mkString(", ")}" + debug(msg) + client.onBuildLogMessage(new LogMessageParams(MessageType.ERROR, msg)) + } + + // only the successful results + val successes = results.values.map(_.value).asInstanceOf[Seq[W]] + successes + .flatMap { v => + try { + Seq(f(ev, state, id, state.bspModulesById(id)._1, v)) + } catch { + case NonFatal(e) => + val msg = s"Request '$prefix' failed for ${id.getUri}: ${failures.mkString(", ")}" + debug(msg) + client.onBuildLogMessage(new LogMessageParams(MessageType.ERROR, msg)) + Seq() + } + } } agg(evaluated.flatten.toSeq.asJava) } + } /** * Given a function that take input of type T and return output of type V, From 95cb10f8196db36cc9ef5a1d1561724d76dde5ff Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Mon, 19 Feb 2024 13:36:22 +0100 Subject: [PATCH 2/4] . --- bsp/worker/src/mill/bsp/worker/MillBuildServer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 5b2b67f4987..33e81afc94a 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -77,7 +77,7 @@ import scala.reflect.ClassTag import scala.util.{Failure, Success, Try} import Utils.sanitizeUri import mill.bsp.BspServerResult -import mill.eval.Evaluator.{Results, TaskResult} +import mill.eval.Evaluator.TaskResult import scala.util.chaining.scalaUtilChainingOps import scala.util.control.NonFatal From 748ca1c8412ad8313edecf08993a8e30d1f03d49 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Mon, 19 Feb 2024 15:06:58 +0100 Subject: [PATCH 3/4] cleanup --- .../src/mill/bsp/worker/MillBuildServer.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 33e81afc94a..b8adb5a0790 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -670,13 +670,17 @@ private class MillBuildServer( case (_, TaskResult(res: Result.Failing[_], _)) => res } - if (failures.nonEmpty) { - // somehow report failures to the build client - val msg = s"Request '$prefix' failed for ${id.getUri}: ${failures.mkString(", ")}" + def logError(errorMsg: String) = { + val msg = s"Request '$prefix' failed for ${id.getUri}: ${errorMsg}" debug(msg) client.onBuildLogMessage(new LogMessageParams(MessageType.ERROR, msg)) } + if (failures.nonEmpty) { + // somehow report failures to the build client + logError(failures.mkString(", ")) + } + // only the successful results val successes = results.values.map(_.value).asInstanceOf[Seq[W]] successes @@ -685,9 +689,7 @@ private class MillBuildServer( Seq(f(ev, state, id, state.bspModulesById(id)._1, v)) } catch { case NonFatal(e) => - val msg = s"Request '$prefix' failed for ${id.getUri}: ${failures.mkString(", ")}" - debug(msg) - client.onBuildLogMessage(new LogMessageParams(MessageType.ERROR, msg)) + logError(e.toString) Seq() } } From 005929d249b91c32582b22f3e5c597547bfddb43 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Mon, 19 Feb 2024 15:07:56 +0100 Subject: [PATCH 4/4] . --- bsp/worker/src/mill/bsp/worker/MillBuildServer.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index b8adb5a0790..1e890f59bda 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -677,7 +677,6 @@ private class MillBuildServer( } if (failures.nonEmpty) { - // somehow report failures to the build client logError(failures.mkString(", ")) }