diff --git a/engine/language-server/src/main/scala/org/enso/languageserver/runtime/ContextRegistryProtocol.scala b/engine/language-server/src/main/scala/org/enso/languageserver/runtime/ContextRegistryProtocol.scala index 1dfb5d97f3df..ab534b21119b 100644 --- a/engine/language-server/src/main/scala/org/enso/languageserver/runtime/ContextRegistryProtocol.scala +++ b/engine/language-server/src/main/scala/org/enso/languageserver/runtime/ContextRegistryProtocol.scala @@ -161,7 +161,8 @@ object ContextRegistryProtocol { /** An information about computed expression. */ case object Value extends Payload - case class Pending(message: Option[String], progress: Option[Double]) extends Payload; + case class Pending(message: Option[String], progress: Option[Double]) + extends Payload; /** Indicates that the expression was computed to an error. * @@ -217,7 +218,7 @@ object ContextRegistryProtocol { case m: Payload.Pending => Encoder[Payload.Pending] - .apply(m) + .apply(m) .deepMerge( Json.obj(CodecField.Type -> PayloadType.Pending.asJson) ) diff --git a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/CacheInvalidation.scala b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/CacheInvalidation.scala index 128434bed8a7..62f12f953c67 100644 --- a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/CacheInvalidation.scala +++ b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/CacheInvalidation.scala @@ -114,10 +114,9 @@ object CacheInvalidation { */ def runAll( stack: Iterable[InstrumentFrame], - instructions: Iterable[CacheInvalidation], - invalidatedKeys: java.util.Set[UUID] + instructions: Iterable[CacheInvalidation] ): Unit = - instructions.foreach(run(stack, _, invalidatedKeys)) + instructions.foreach(run(stack, _)) /** Run a sequence of invalidation instructions on all visualisations. * @@ -158,14 +157,13 @@ object CacheInvalidation { */ def run( stack: Iterable[InstrumentFrame], - instruction: CacheInvalidation, - invalidatedKeys: java.util.Set[UUID] + instruction: CacheInvalidation ): Unit = { val frames = instruction.elements match { case StackSelector.All => stack case StackSelector.Top => stack.headOption.toSeq } - run(frames, instruction.command, instruction.indexes, invalidatedKeys) + run(frames, instruction.command, instruction.indexes) } /** Run cache invalidation of a multiple instrument frames. @@ -177,12 +175,9 @@ object CacheInvalidation { private def run( frames: Iterable[InstrumentFrame], command: Command, - indexes: Set[IndexSelector], - invalidatedKeys: java.util.Set[UUID] + indexes: Set[IndexSelector] ): Unit = { - frames.foreach(frame => - run(frame.cache, frame.syncState, command, indexes, invalidatedKeys) - ) + frames.foreach(frame => run(frame.cache, frame.syncState, command, indexes)) } /** Run cache invalidation of a single instrument frame. @@ -226,25 +221,21 @@ object CacheInvalidation { cache: RuntimeCache, syncState: UpdatesSynchronizationState, command: Command, - indexes: Set[IndexSelector], - invalidatedKeys: java.util.Set[UUID] + indexes: Set[IndexSelector] ): Unit = command match { case Command.InvalidateAll => - invalidatedKeys.addAll(cache.getKeys) cache.clear() indexes.foreach(clearIndex(_, cache)) case Command.InvalidateKeys(keys) => keys.foreach { key => cache.remove(key) - invalidatedKeys.add(key) indexes.foreach(clearIndexKey(key, _, cache)) } case Command.InvalidateStale(scope) => val staleKeys = cache.getKeys.asScala.diff(scope.toSet) staleKeys.foreach { key => cache.remove(key) - invalidatedKeys.add(key) indexes.foreach(clearIndexKey(key, _, cache)) syncState.invalidate(key) } diff --git a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/command/RecomputeContextCmd.scala b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/command/RecomputeContextCmd.scala index 7974d8c16174..782cdfdede66 100644 --- a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/command/RecomputeContextCmd.scala +++ b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/command/RecomputeContextCmd.scala @@ -45,8 +45,7 @@ class RecomputeContextCmd( .map(CacheInvalidation(CacheInvalidation.StackSelector.Top, _)) CacheInvalidation.runAll( stack, - cacheInvalidationCommands, - new java.util.HashSet[java.util.UUID]() + cacheInvalidationCommands ) reply(Api.RecomputeContextResponse(request.contextId)) true diff --git a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/EnsureCompiledJob.scala b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/EnsureCompiledJob.scala index f90c8fc5a057..bbfff6e50cc7 100644 --- a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/EnsureCompiledJob.scala +++ b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/EnsureCompiledJob.scala @@ -29,7 +29,6 @@ import java.util.logging.Level import scala.jdk.CollectionConverters._ import scala.jdk.OptionConverters._ -import java.util.UUID /** A job that ensures that specified files are compiled. * @@ -46,7 +45,7 @@ final class EnsureCompiledJob(protected val files: Iterable[File]) try { val compilationResult = ensureCompiledFiles(files) - setCacheWeights(new java.util.HashSet[java.util.UUID]()) + setCacheWeights() compilationResult } finally { ctx.locking.releaseWriteCompilationLock() @@ -306,11 +305,10 @@ final class EnsureCompiledJob(protected val files: Iterable[File]) changeset, module.getSource.getCharacters ) - val invalidatedKeys = new java.util.HashSet[java.util.UUID](); ctx.contextManager.getAllContexts.values .foreach { stack => if (stack.nonEmpty && isStackInModule(module.getName, stack)) { - CacheInvalidation.runAll(stack, invalidationCommands, invalidatedKeys) + CacheInvalidation.runAll(stack, invalidationCommands) } } CacheInvalidation.runAllVisualisations( @@ -318,42 +316,6 @@ final class EnsureCompiledJob(protected val files: Iterable[File]) invalidationCommands ) - if (!invalidatedKeys.isEmpty()) { - System.err.println("Invalidated: " + invalidatedKeys) - val invalidatedKeysScala = invalidatedKeys.asScala.toSet - ctx.contextManager.getAllContexts.foreachEntry((contextId, stack) => { - val knownKeys = stack.top.cache.getWeights.entrySet - val cachedKeys = stack.top.cache.getKeys - val pendingKeys = new java.util.HashSet[UUID]() - - knownKeys.forEach(e => { - if (e.getValue > 0) { - if (!cachedKeys.contains(e.getKey)) { - pendingKeys.add(e.getKey) - System.out.println(" found key with " + e.getValue + " key: " + e.getKey) - } - } - }); - val ids = invalidatedKeysScala.map { key => - // pendingKeys.asScala.toSet.map { key => - Api.ExpressionUpdate( - key, - None, - None, - Vector.empty, - true, - Api.ExpressionUpdate.Payload.Pending(None, None) - ) - } - - System.err.println(" ignore pendingKeys: " + pendingKeys) - val msg = Api.Response( - Api.ExpressionUpdates(contextId, ids) - ) - ctx.endpoint.sendToClient(msg) - }) - } - val invalidatedVisualisations = ctx.contextManager.getInvalidatedVisualisations( module.getName, @@ -409,9 +371,7 @@ final class EnsureCompiledJob(protected val files: Iterable[File]) else CompilationStatus.Success - private def setCacheWeights( - invalidatedKeys: java.util.Set[java.util.UUID] - )(implicit ctx: RuntimeContext): Unit = { + private def setCacheWeights()(implicit ctx: RuntimeContext): Unit = { ctx.contextManager.getAllContexts.values.foreach { stack => getCacheMetadata(stack).foreach { metadata => CacheInvalidation.run( @@ -419,8 +379,7 @@ final class EnsureCompiledJob(protected val files: Iterable[File]) CacheInvalidation( CacheInvalidation.StackSelector.Top, CacheInvalidation.Command.SetMetadata(metadata) - ), - invalidatedKeys + ) ) } } diff --git a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/ProgramExecutionSupport.scala b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/ProgramExecutionSupport.scala index 9bcb591e240c..997bbbfc2fe1 100644 --- a/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/ProgramExecutionSupport.scala +++ b/engine/runtime/src/main/scala/org/enso/interpreter/instrument/job/ProgramExecutionSupport.scala @@ -41,6 +41,7 @@ import org.enso.polyglot.LanguageInfo import org.enso.polyglot.runtime.Runtime.Api import org.enso.polyglot.runtime.Runtime.Api.ContextId +import scala.jdk.CollectionConverters._ import scala.jdk.OptionConverters._ /** Provides support for executing Enso code. Adds convenient methods to @@ -95,12 +96,45 @@ object ProgramExecutionSupport { enterables += fun.getExpressionId -> fun.getCall } + def notifyPendingCacheItems(cache: RuntimeCache): Unit = { + val knownKeys = cache.getWeights.entrySet + val cachedKeys = cache.getKeys + val pendingKeys = new java.util.HashSet[UUID]() + + knownKeys.forEach(e => { + if (e.getValue > 0) { + if (!cachedKeys.contains(e.getKey)) { + pendingKeys.add(e.getKey) + System.out.println( + " found key with " + e.getValue + " key: " + e.getKey + ) + } + } + }); + val ids = pendingKeys.asScala.toSet.map { key => + Api.ExpressionUpdate( + key, + None, + None, + Vector.empty, + true, + Api.ExpressionUpdate.Payload.Pending(None, None) + ) + } + + val msg = Api.Response( + Api.ExpressionUpdates(contextId, ids) + ) + ctx.endpoint.sendToClient(msg) + } + executionFrame match { case ExecutionFrame( ExecutionItem.Method(module, cons, function), cache, syncState ) => + notifyPendingCacheItems(cache) ctx.executionService.execute( module.toString, cons.item, @@ -125,6 +159,7 @@ object ProgramExecutionSupport { .orElseThrow(() => new ModuleNotFoundForExpressionIdException(expressionId) ) + notifyPendingCacheItems(cache) ctx.executionService.execute( module, callData, diff --git a/engine/runtime/src/test/scala/org/enso/interpreter/test/instrument/InstrumentTestContext.scala b/engine/runtime/src/test/scala/org/enso/interpreter/test/instrument/InstrumentTestContext.scala index 628f1a322a73..0ca3e75e790d 100644 --- a/engine/runtime/src/test/scala/org/enso/interpreter/test/instrument/InstrumentTestContext.scala +++ b/engine/runtime/src/test/scala/org/enso/interpreter/test/instrument/InstrumentTestContext.scala @@ -32,10 +32,14 @@ class InstrumentTestContext { n: Int, timeoutSeconds: Long = 60 ): List[Api.Response] = { - receiveNWithFilter(n, { + receiveNWithFilter( + n, + { case Some(Api.Response(None, Api.ExpressionUpdates(_, _))) => false - case _ => true - }, timeoutSeconds) + case _ => true + }, + timeoutSeconds + ) } def receiveNIgnoreStdLib( @@ -45,7 +49,6 @@ class InstrumentTestContext { receiveNWithFilter(n, (_ => true), timeoutSeconds) } - private def receiveNWithFilter( n: Int, f: (Any => Boolean),