Skip to content

Commit

Permalink
cap number of scala-cli servers
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Nov 28, 2023
1 parent c9aedb2 commit 7f33208
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class BspMetalsLspService(
folder,
folderVisibleName,
headDoctor,
maxScalaCliServers = 3,
) {
import serverInputs._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class FallbackMetalsLspService(
folder,
folderVisibleName,
headDoctor,
maxScalaCliServers = 10,
) {

override protected def doctor: Doctor =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ abstract class MetalsLspService(
folder: AbsolutePath,
folderVisibleName: Option[String],
headDoctor: HeadDoctor,
maxScalaCliServers: Int,
) extends Folder(folder, folderVisibleName, isKnownMetalsProject = true)
with Cancelable
with TextDocumentService {
Expand Down Expand Up @@ -866,6 +867,7 @@ abstract class MetalsLspService(
.foreach(focusedDocumentBuildTarget.set)
// unpublish diagnostic for dependencies
interactiveSemanticdbs.didFocus(path)
scalaCli.didFocus(path)
// Don't trigger compilation on didFocus events under cascade compilation
// because save events already trigger compile in inverse dependencies.
if (path.isDependencySource(folder)) {
Expand Down Expand Up @@ -1601,6 +1603,7 @@ abstract class MetalsLspService(
() => userConfig,
parseTreesAndPublishDiags,
buildTargets,
maxScalaCliServers,
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package scala.meta.internal.metals.scalacli
import java.io.File
import java.util.concurrent.atomic.AtomicReference

import scala.collection.immutable.Queue
import scala.concurrent.ExecutionContextExecutorService
import scala.concurrent.Future

Expand Down Expand Up @@ -39,16 +40,17 @@ class ScalaCliServers(
userConfig: () => UserConfiguration,
parseTreesAndPublishDiags: Seq[AbsolutePath] => Future[Unit],
buildTargets: BuildTargets,
maxServers: Int,
)(implicit ec: ExecutionContextExecutorService)
extends Cancelable {
private val serversRef: AtomicReference[Set[ScalaCli]] = new AtomicReference(
Set.empty
)

private val serversRef: AtomicReference[Queue[ScalaCli]] =
new AtomicReference(Queue.empty)

private lazy val localScalaCli: Option[Seq[String]] =
ScalaCli.localScalaCli(userConfig())

def servers: List[ScalaCli] = serversRef.get().toList
def servers: Iterable[ScalaCli] = serversRef.get()

def setupIDE(path: AbsolutePath): Future[Unit] = {
localScalaCli
Expand Down Expand Up @@ -96,17 +98,18 @@ class ScalaCliServers(
.map(server => (server.lastImportedBuild, server.buildTargetsData))
.toList

def buildServers: List[BuildServerConnection] = servers.flatMap(_.buildServer)
def buildServers: Iterable[BuildServerConnection] =
servers.flatMap(_.buildServer)

def cancel(): Unit = {
val servers = serversRef.getAndSet(Set.empty)
val servers = serversRef.getAndSet(Queue.empty)
servers.foreach(_.cancel())
}

def loaded(path: AbsolutePath): Boolean =
servers.exists(_.path.toNIO.startsWith(path.toNIO))

def paths: List[AbsolutePath] = servers.map(_.path)
def paths: Iterable[AbsolutePath] = servers.map(_.path)

def start(path: AbsolutePath): Future[Unit] = {
val scalaCli =
Expand All @@ -128,21 +131,32 @@ class ScalaCliServers(

val prevServers = serversRef.getAndUpdate { servers =>
if (servers.exists(_.path == path)) servers
else servers + scalaCli
else {
if (servers.size == maxServers) servers.drop(1) :+ scalaCli
else servers :+ scalaCli
}
}

prevServers
.find(_.path == path)
.getOrElse {
buildTargets.addData(scalaCli.buildTargetsData)
scalaCli
}
.start()
val (newServer, outServer) =
prevServers
.find(_.path == path)
.map((_, None))
.getOrElse {
buildTargets.addData(scalaCli.buildTargetsData)
val outServer =
Option.when(servers.size == 10)(prevServers.dequeue._1)
(scalaCli, outServer)
}

for {
_ <- outServer.map(_.stop()).getOrElse(Future.unit)
_ <- newServer.start()
} yield ()
}

def stop(): Future[Unit] = {
val servers = serversRef.getAndSet(Set.empty)
Future.sequence(servers.map(_.stop())).ignoreValue
val servers = serversRef.getAndSet(Queue.empty)
Future.sequence(servers.map(_.stop()).toSeq).ignoreValue
}

def stop(path: AbsolutePath): Future[Unit] = {
Expand All @@ -156,4 +170,13 @@ class ScalaCliServers(
.getOrElse(Future.successful(()))
}

def didFocus(path: AbsolutePath): Queue[ScalaCli] =
serversRef.getAndUpdate { servers =>
servers.find(server => path.startWith(server.path)) match {
case Some(foundServer) =>
servers.filterNot(_ == foundServer) :+ foundServer
case None => servers
}
}

}

0 comments on commit 7f33208

Please sign in to comment.