Skip to content

Commit

Permalink
Integrate downloading cache with PackageRepository
Browse files Browse the repository at this point in the history
  • Loading branch information
radeusgd committed Jul 20, 2021
1 parent 322a9f6 commit 83f64aa
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.enso.compiler.Compiler;
import org.enso.compiler.PackageRepository;
import org.enso.compiler.data.CompilerConfig;
import org.enso.distribution.locking.ThreadSafeFileLockManager;
import org.enso.editions.LibraryName;
import org.enso.interpreter.Language;
import org.enso.interpreter.OptionsHelper;
Expand Down Expand Up @@ -101,11 +102,19 @@ public void initialize() {
var languageHome =
OptionsHelper.getLanguageHomeOverride(environment).or(() -> Optional.ofNullable(home));

var distributionManager = RuntimeDistributionManager$.MODULE$;

// TODO [RW] Once #1890 is implemented, this will need to connect to the Language Server's
// LockManager.
var lockManager = new ThreadSafeFileLockManager(distributionManager.paths().locks());
var resourceManager = new org.enso.distribution.locking.ResourceManager(lockManager);

packageRepository =
PackageRepository.initializeRepository(
OptionConverters.toScala(projectPackage),
OptionConverters.toScala(languageHome),
RuntimeDistributionManager$.MODULE$,
distributionManager,
resourceManager,
this,
builtins,
notificationHandler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.enso.compiler

import com.oracle.truffle.api.TruffleFile
import com.typesafe.scalalogging.Logger
import org.enso.distribution.locking.ResourceManager
import org.enso.distribution.{DistributionManager, EditionManager, LanguageHome}
import org.enso.editions.{DefaultEdition, LibraryName, LibraryVersion}
import org.enso.interpreter.instrument.NotificationHandler
Expand Down Expand Up @@ -329,6 +330,7 @@ object PackageRepository {
projectPackage: Option[Package[TruffleFile]],
languageHome: Option[String],
distributionManager: DistributionManager,
resourceManager: ResourceManager,
context: Context,
builtins: Builtins,
notificationHandler: NotificationHandler
Expand All @@ -344,6 +346,9 @@ object PackageRepository {
val resolvingLibraryProvider =
new DefaultLibraryProvider(
distributionManager = distributionManager,
resourceManager = resourceManager,
lockUserInterface = notificationHandler,
progressReporter = notificationHandler,
languageHome = homeManager,
edition = edition,
preferLocalLibraries =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ package org.enso.interpreter.instrument

import com.typesafe.scalalogging.Logger
import org.enso.cli.ProgressBar
import org.enso.cli.task.{
ProgressNotification,
ProgressNotificationForwarder,
ProgressReporter,
TaskProgress
}
import org.enso.cli.task.{ProgressNotification, ProgressReporter, TaskProgress}
import org.enso.distribution.ProgressAndLockNotificationForwarder
import org.enso.distribution.locking.{LockUserInterface, Resource}
import org.enso.editions.{LibraryName, LibraryVersion}
import org.enso.polyglot.runtime.Runtime.{Api, ApiResponse}

Expand All @@ -16,7 +13,7 @@ import java.nio.file.Path
/** A class that forwards notifications about loaded libraries and long-running
* tasks to the user interface.
*/
trait NotificationHandler extends ProgressReporter {
trait NotificationHandler extends ProgressReporter with LockUserInterface {

/** Called when a library has been loaded.
*
Expand All @@ -40,6 +37,8 @@ object NotificationHandler {
*/
object TextMode extends NotificationHandler {

private lazy val logger = Logger[TextMode.type]

/** @inheritdoc */
override def addedLibrary(
libraryName: LibraryName,
Expand All @@ -51,11 +50,16 @@ object NotificationHandler {

/** @inheritdoc */
override def trackProgress(message: String, task: TaskProgress[_]): Unit = {
Logger[TextMode.type].info(message)
logger.info(message)
if (System.console() != null) {
ProgressBar.waitWithProgress(task)
}
}

override def startWaitingForResource(resource: Resource): Unit =
logger.warn(resource.waitMessage)

override def finishWaitingForResource(resource: Resource): Unit = ()
}

/** A [[NotificationHandler]] that forwards messages to other
Expand All @@ -76,6 +80,14 @@ object NotificationHandler {
override def trackProgress(message: String, task: TaskProgress[_]): Unit =
for (listener <- listeners) listener.trackProgress(message, task)

/** @inheritdoc */
override def startWaitingForResource(resource: Resource): Unit =
for (listener <- listeners) listener.startWaitingForResource(resource)

/** @inheritdoc */
override def finishWaitingForResource(resource: Resource): Unit =
for (listener <- listeners) listener.finishWaitingForResource(resource)

/** Registers a new listener. */
def addListener(listener: NotificationHandler): Unit =
listeners ::= listener
Expand All @@ -86,8 +98,8 @@ object NotificationHandler {
* the IDE.
*/
class InteractiveMode(endpoint: Endpoint)
extends NotificationHandler
with ProgressNotificationForwarder {
extends ProgressAndLockNotificationForwarder
with NotificationHandler {
private val logger = Logger[InteractiveMode]

private def sendMessage(message: ApiResponse): Unit = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.enso.distribution

import org.enso.cli.task.{
ProgressNotification,
ProgressNotificationForwarder,
ProgressUnit
}
import org.enso.distribution.locking.{LockUserInterface, Resource}

import java.util.UUID

abstract class ProgressAndLockNotificationForwarder
extends ProgressNotificationForwarder
with LockUserInterface {
private val waitingForResources =
collection.concurrent.TrieMap[String, UUID]()

/** @inheritdoc */
override def startWaitingForResource(resource: Resource): Unit = {
val uuid = UUID.randomUUID()
sendProgressNotification(
ProgressNotification.TaskStarted(
uuid,
None,
ProgressUnit.Unspecified
)
)
sendProgressNotification(
ProgressNotification.TaskUpdate(
uuid,
Some(resource.waitMessage),
0
)
)
waitingForResources.put(resource.name, uuid)
}

/** @inheritdoc */
override def finishWaitingForResource(resource: Resource): Unit = {
for (uuid <- waitingForResources.remove(resource.name)) {
sendProgressNotification(ProgressNotification.TaskSuccess(uuid))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,10 @@ class ResourceManager(lockManager: LockManager) {
*/
def startUsingTemporaryDirectory(): Unit = {
if (temporaryDirectoryLock.isDefined) {
throw new IllegalStateException(
"Temporary directory lock has been acquired twice."
)
logger.trace("The temporary directory was already in-use.")
return
}

val lock = lockManager.acquireLockWithWaitingAction(
TemporaryDirectory.name,
LockType.Shared,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package org.enso.librarymanager

import com.typesafe.scalalogging.Logger
import org.enso.distribution.{DistributionManager, LanguageHome}
import org.enso.cli.task.ProgressReporter
import org.enso.distribution.locking.{LockUserInterface, ResourceManager}
import org.enso.distribution.{
DistributionManager,
LanguageHome,
TemporaryDirectoryManager
}
import org.enso.editions.{Editions, LibraryName, LibraryVersion}
import org.enso.librarymanager.local.DefaultLocalLibraryProvider
import org.enso.librarymanager.published.bundles.LocalReadOnlyRepository
import org.enso.librarymanager.published.cache.NoOpCache
import org.enso.librarymanager.published.cache.DownloadingLibraryCache
import org.enso.librarymanager.published.{
DefaultPublishedLibraryProvider,
PublishedLibraryProvider
Expand All @@ -17,12 +23,16 @@ import java.nio.file.Path
/** A helper class for loading libraries.
*
* @param distributionManager a distribution manager
* @param resourceManager a resource manager
* @param languageHome a language home which may contain bundled libraries
* @param edition the edition used in the project
* @param preferLocalLibraries project setting whether to use local libraries
*/
class DefaultLibraryProvider(
distributionManager: DistributionManager,
resourceManager: ResourceManager,
lockUserInterface: LockUserInterface,
progressReporter: ProgressReporter,
languageHome: Option[LanguageHome],
edition: Editions.ResolvedEdition,
preferLocalLibraries: Boolean
Expand All @@ -36,8 +46,13 @@ class DefaultLibraryProvider(

private val resolver = LibraryResolver(localLibraryProvider)

// TODO [RW] actual cache that can download libraries will be implemented in #1772
private val primaryCache = new NoOpCache
private val primaryCache = new DownloadingLibraryCache(
cacheRoot = distributionManager.paths.cachedLibraries,
TemporaryDirectoryManager(distributionManager, resourceManager),
resourceManager,
lockUserInterface,
progressReporter
)
private val additionalCacheLocations = {
val engineBundleRoot = languageHome.map(_.libraries)
val locations =
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,28 @@ package org.enso.projectmanager.service.versionmanagement
import akka.actor.ActorRef
import com.typesafe.scalalogging.Logger
import nl.gn0s1s.bump.SemVer
import org.enso.cli.task.{
ProgressNotification,
ProgressNotificationForwarder,
ProgressUnit
}
import org.enso.distribution.locking.Resource
import org.enso.cli.task.ProgressNotification
import org.enso.distribution.ProgressAndLockNotificationForwarder
import org.enso.runtimeversionmanager.components.{
GraalVMVersion,
RuntimeVersionManagementUserInterface
}

import java.util.UUID

/** A [[RuntimeVersionManagementUserInterface]] that sends
* [[ProgressNotification]] to the specified actors (both for usual tasks and
* indeterminate progress when waiting on locks).
*
* @param progressTracker the actor to send progress updates to
* @param progressTracker the actor to send progress updates to
* @param allowMissingComponents specifies if missing components should be
* automatically installed
* @param allowBrokenComponents specifies if broken components can be installed
* @param allowBrokenComponents specifies if broken components can be installed
*/
class ControllerInterface(
progressTracker: ActorRef,
allowMissingComponents: Boolean,
allowBrokenComponents: Boolean
) extends RuntimeVersionManagementUserInterface
with ProgressNotificationForwarder {
) extends ProgressAndLockNotificationForwarder
with RuntimeVersionManagementUserInterface {

/** @inheritdoc */
override def shouldInstallMissingEngine(version: SemVer): Boolean =
Expand All @@ -48,32 +42,6 @@ class ControllerInterface(
override def logInfo(message: => String): Unit =
Logger[ControllerInterface].info(message)

private val waitingForResources =
collection.concurrent.TrieMap[String, UUID]()

/** @inheritdoc */
override def startWaitingForResource(resource: Resource): Unit = {
val uuid = UUID.randomUUID()
progressTracker ! ProgressNotification.TaskStarted(
uuid,
None,
ProgressUnit.Unspecified
)
progressTracker ! ProgressNotification.TaskUpdate(
uuid,
Some(resource.waitMessage),
0
)
waitingForResources.put(resource.name, uuid)
}

/** @inheritdoc */
override def finishWaitingForResource(resource: Resource): Unit = {
for (uuid <- waitingForResources.remove(resource.name)) {
progressTracker ! ProgressNotification.TaskSuccess(uuid)
}
}

/** @inheritdoc */
override def sendProgressNotification(
notification: ProgressNotification
Expand Down

0 comments on commit 83f64aa

Please sign in to comment.