Skip to content

Commit

Permalink
Cache expression compiler jars
Browse files Browse the repository at this point in the history
  • Loading branch information
adpi2 committed Sep 21, 2021
1 parent a747cfa commit ec508fc
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 25 deletions.
2 changes: 2 additions & 0 deletions backend/src/main/scala/bloop/BloopComponentsLock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ sealed trait ComponentLock extends GlobalLock {
object BloopComponentsLock extends ComponentLock

object SemanticDBCacheLock extends ComponentLock

object ExpressionCompilerCacheLock extends ComponentLock
30 changes: 5 additions & 25 deletions frontend/src/main/scala/bloop/dap/BloopDebuggeeRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import monix.execution.Scheduler
import java.net.URLClassLoader
import scala.collection.mutable
import scala.annotation.tailrec
import bloop.engine.caches.ExpressionCompilerCache

abstract class BloopDebuggeeRunner(initialState: State, ioScheduler: Scheduler)
extends DebuggeeRunner {
Expand Down Expand Up @@ -210,35 +211,14 @@ object BloopDebuggeeRunner {
logger: Logger,
ioScheduler: Scheduler
): Option[ClassLoader] = {
import ch.epfl.scala.debugadapter.BuildInfo._
import coursier._
val scalaVersion = scalaInstance.version
val module = s"${expressionCompilerName}_$scalaVersion"
val expressionCompilerDep = Dependency(
Module(
Organization(expressionCompilerOrganization),
ModuleName(module)
),
expressionCompilerVersion
)
val resolution = Fetch()
.addDependencies(expressionCompilerDep)
.either()(ioScheduler)

resolution match {
ExpressionCompilerCache.fetch(scalaInstance.version, logger) match {
case Left(error) =>
logger.warn(
s"Failed fetching $expressionCompilerOrganization:$module:$expressionCompilerVersion"
)
logger.warn(error.getMessage)
logger.warn(error)
logger.warn(s"Expression evaluation will not work.")
None
case Right(files) =>
val expressionCompilerJar = files
.find(_.getName.startsWith(expressionCompilerName))
.map(_.toURI.toURL)
case Right(expressionCompilerJar) =>
val evaluationClassLoader =
new URLClassLoader(expressionCompilerJar.toArray, scalaInstance.loader)
new URLClassLoader(Array(expressionCompilerJar.toFile.toURI.toURL), scalaInstance.loader)
Some(evaluationClassLoader)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package bloop.engine.caches

import bloop.DependencyResolution
import bloop.ExpressionCompilerCacheLock
import bloop.io.AbsolutePath
import bloop.io.Paths
import bloop.logging.Logger
import ch.epfl.scala.debugadapter.BuildInfo
import sbt.internal.inc.BloopComponentCompiler
import sbt.internal.inc.BloopComponentManager
import sbt.internal.inc.IfMissing

import scala.util.Failure
import scala.util.Success
import scala.util.Try

object ExpressionCompilerCache {
import ch.epfl.scala.debugadapter.BuildInfo._

private val cacheDirectory = Paths.getCacheDirectory(expressionCompilerName)
private val provider = BloopComponentCompiler.getComponentProvider(cacheDirectory)
private val manager =
new BloopComponentManager(ExpressionCompilerCacheLock, provider, secondaryCacheDir = None)

def fetch(
scalaVersion: String,
logger: Logger
): Either[String, AbsolutePath] = {
val module = s"${expressionCompilerName}_$scalaVersion"
val expressionCompilerId = s"$expressionCompilerOrganization.$module.$expressionCompilerVersion"

def attemptResolution(): Either[String, AbsolutePath] = {
import bloop.engine.ExecutionContext.ioScheduler
val artifact = DependencyResolution.Artifact(
expressionCompilerOrganization,
module,
expressionCompilerVersion
)
DependencyResolution.resolveWithErrors(List(artifact), logger)(ioScheduler) match {
case Left(error) => Left(error.getMessage())
case Right(paths) =>
paths
.find(_.syntax.contains(module))
.toRight(s"Missing $module in resolved jars ${paths.map(_.syntax).mkString(",")}")
}
}

Try(manager.file(expressionCompilerId)(IfMissing.Fail)) match {
case Success(pluginPath) => Right(AbsolutePath(pluginPath))
case Failure(exception) =>
val resolution = attemptResolution()
resolution.foreach(jar => manager.define(expressionCompilerId, Seq(jar.toFile)))
resolution
}
}
}

0 comments on commit ec508fc

Please sign in to comment.