From e81e5db1909d90af1501703e7b4d6f760247c85e Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Fri, 26 Jul 2024 12:55:29 +0200 Subject: [PATCH] improvement: Timeout when resolving mtags for a long time Otherwise this timeouts tests and can actually hang metals totally. --- .../meta/internal/metals/MtagsResolver.scala | 29 ++++++++++++++----- .../metals/doctor/ProblemResolver.scala | 3 +- .../main/scala/tests/TestMtagsResolver.scala | 6 +++- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala b/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala index 2b81d72c9aa..7b0f607d572 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala @@ -2,6 +2,9 @@ package scala.meta.internal.metals import java.util.concurrent.ConcurrentHashMap +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.control.NonFatal @@ -14,14 +17,18 @@ trait MtagsResolver { * Try and resolve mtags module for a given version of Scala. * @return information to use and load the presentation compiler implementation */ - def resolve(scalaVersion: String): Option[MtagsBinaries] + def resolve(scalaVersion: String)(implicit + ec: ExecutionContext + ): Option[MtagsBinaries] /** * Check if a given Scala version is supported in Metals. * * @param version Scala version to check */ - def isSupportedScalaVersion(version: String): Boolean = + def isSupportedScalaVersion(version: String)(implicit + ec: ExecutionContext + ): Boolean = resolve(version).isDefined /** @@ -102,7 +109,9 @@ object MtagsResolver { def isSupportedInOlderVersion(version: String): Boolean = removedScalaVersions.contains(version) - def resolve(scalaVersion: String): Option[MtagsBinaries] = { + def resolve( + scalaVersion: String + )(implicit ec: ExecutionContext): Option[MtagsBinaries] = { if (hasStablePresentationCompiler(scalaVersion)) resolve( scalaVersion, @@ -130,7 +139,7 @@ object MtagsResolver { scalaVersion: String, original: Option[String], resolveType: ResolveType.Value, - ): Option[MtagsBinaries] = { + )(implicit ec: ExecutionContext): Option[MtagsBinaries] = { def fetch(fetchResolveType: ResolveType.Value, tries: Int = 5): State = try { @@ -143,12 +152,16 @@ object MtagsResolver { s"$scalaVersion is no longer supported in the current Metals versions, using the last known supported version $metalsVersion" ) } - val jars = fetchResolveType match { - case ResolveType.StablePC => - Embedded.downloadScala3PresentationCompiler(scalaVersion) - case _ => Embedded.downloadMtags(scalaVersion, metalsVersion) + val jarsFuture = Future { + fetchResolveType match { + case ResolveType.StablePC => + Embedded.downloadScala3PresentationCompiler(scalaVersion) + case _ => Embedded.downloadMtags(scalaVersion, metalsVersion) + } } + val jars = Await.result(jarsFuture, 60.seconds) + State.Success( MtagsBinaries.Artifacts( scalaVersion, diff --git a/metals/src/main/scala/scala/meta/internal/metals/doctor/ProblemResolver.scala b/metals/src/main/scala/scala/meta/internal/metals/doctor/ProblemResolver.scala index baf1dfb7d06..91252d82909 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/doctor/ProblemResolver.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/doctor/ProblemResolver.scala @@ -1,6 +1,7 @@ package scala.meta.internal.metals.doctor import scala.collection.mutable.ListBuffer +import scala.concurrent.ExecutionContext import scala.meta.internal.bsp.BspSession import scala.meta.internal.metals.BloopServers @@ -23,7 +24,7 @@ class ProblemResolver( currentBuildServer: () => Option[BspSession], isTestExplorerProvider: () => Boolean, javaInfo: () => Option[JavaInfo], -) { +)(implicit ec: ExecutionContext) { def isUnsupportedBloopVersion(): Boolean = { currentBuildServer() match { diff --git a/tests/unit/src/main/scala/tests/TestMtagsResolver.scala b/tests/unit/src/main/scala/tests/TestMtagsResolver.scala index 760f2c95a7b..52062c96bf4 100644 --- a/tests/unit/src/main/scala/tests/TestMtagsResolver.scala +++ b/tests/unit/src/main/scala/tests/TestMtagsResolver.scala @@ -1,5 +1,7 @@ package tests +import scala.concurrent.ExecutionContext + import scala.meta.internal.metals.MtagsBinaries import scala.meta.internal.metals.MtagsResolver import scala.meta.internal.metals.ScalaVersions @@ -19,7 +21,9 @@ class TestMtagsResolver(checkCoursier: Boolean) extends MtagsResolver { Some(MtagsBinaries.BuildIn) else None - override def resolve(scalaVersion: String): Option[MtagsBinaries] = { + override def resolve( + scalaVersion: String + )(implicit ec: ExecutionContext): Option[MtagsBinaries] = { if (checkCoursier) default.resolve(scalaVersion).orElse(localCheck(scalaVersion)) else localCheck(scalaVersion)