Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre compute suggestion db during build time #5698

Merged

Conversation

4e6
Copy link
Contributor

@4e6 4e6 commented Feb 20, 2023

Pull Request Description

Close #5068

Cache suggestions during the buildEngineDistribution command, and read them from the disk when the library is loaded. Initial graph coloring takes ~20 seconds vs ~25 seconds on the develop branch.

peek-develop-branch.webm
peek-suggestions-branch.webm

Important Notes

Checklist

Please include the following checklist in your PR:

  • The documentation has been updated if necessary.
  • All code conforms to the
    Scala,
    Java,
    and
    Rust
    style guides.
  • All code has been tested:
    • Unit tests have been written where possible.
    • If GUI codebase was changed: Enso GUI was tested when built using BOTH
      ./run ide build and ./run ide watch.

Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Dmitry, I think I know what to do now.

@JaroslavTulach JaroslavTulach self-assigned this Feb 20, 2023
@@ -493,6 +465,13 @@ final class SuggestionsHandler(
updates.foreach(sessionRouter ! _)
context.become(initialized(name, graph, clients, state))

case libraryLoaded: Api.LibraryLoaded =>
logger.debug(
Copy link
Member

@JaroslavTulach JaroslavTulach Feb 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@4e6's idea is to deliver the cached suggestion.json here. However I haven't hit a breakpoint placed here yet. I am not sure who's supposed to deliver this message? Probably we are missing a call to NotificationHandler.addListener that would register SuggestionHandler. Probably the listener shall be attached when case InitializedEvent.TruffleContextInitialized is delivered - by where can I find the EnsoContext at that moment?

Copy link
Member

@JaroslavTulach JaroslavTulach Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One has to subscribe to Akka event bus to get the notification - f480e03

But now there is another problem: The SuggestionSerializationManager is in runtime, while this code is in language-server - how shall these two talk to each other? I believe this "library added" notification is send from following stacktrace:

at org.enso.interpreter.instrument.Endpoint.sendToClient(Handler.scala:48)
at org.enso.interpreter.instrument.NotificationHandler$InteractiveMode.sendMessage(NotificationHandler.scala:110)
at org.enso.interpreter.instrument.NotificationHandler$InteractiveMode.addedLibrary(NotificationHandler.scala:123)
at org.enso.interpreter.instrument.NotificationHandler$Forwarder.$anonfun$addedLibrary$1(NotificationHandler.scala:80)
at org.enso.interpreter.instrument.NotificationHandler$Forwarder.$anonfun$addedLibrary$1$adapted(NotificationHandler.scala:79)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.enso.interpreter.instrument.NotificationHandler$Forwarder.addedLibrary(NotificationHandler.scala:79)
at org.enso.compiler.PackageRepository$Default.registerPackageInternal(PackageRepository.scala:326)

I believe the next step is to modify code in PackageRepository to check whether a suggestion cache exists for the library. If it does, read it and send the content of the suggestions via the Api.LibraryLoaded messages to the "language-server" project that can distribute it further. The following code shall be modified to send also librarySuggestions:

if (isLibrary) {
  val root = Path.of(pkg.root.toString)
  notificationHandler.addedLibrary(libraryName, libraryVersion, root) 
}

JaroslavTulach and others added 5 commits February 22, 2023 05:21
Added a last-modified cache for stdlib files so that we don't generate
index every single time.
…' of enso:enso-org/enso into wip/db/5068-pre-compute-suggestion-db-during-build-time
@4e6 4e6 force-pushed the wip/db/5068-pre-compute-suggestion-db-during-build-time branch from 2215f5a to 6638c9d Compare March 5, 2023 22:45
engine/runtime/src/main/java/org/enso/compiler/Cache.java Outdated Show resolved Hide resolved

@Override
protected byte[] metadata(String sourceDigest, String blobDigest, CachedSuggestions entry) {
var mapper = new ObjectMapper();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the mapper be a field in the cache? Unless I am mistaken the ObjectMapper instance maintains mapping from Class to "functionality". If we create new instance for every library, then its internal mapping must be initialized every time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what I experienced. This causes major slowdowns, which is why I also changed it in #5791

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what I experienced. This causes major slowdowns, which is why I also changed it in #5791

}
}

// CachedSuggestions class is not a record because of a Frgaal bug leading to invalid compilation error.
Copy link
Member

@JaroslavTulach JaroslavTulach Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the error? Maybe updating to new version of frgaal would fix the problem. If I modify:

enso$ git diff
diff --git engine/runtime/src/main/java/org/enso/compiler/SuggestionsCache.java engine/runtime/src/main/java/org/enso/compiler/SuggestionsCache.java
index f5d65b8e0..220c01e9c 100644
--- engine/runtime/src/main/java/org/enso/compiler/SuggestionsCache.java
+++ engine/runtime/src/main/java/org/enso/compiler/SuggestionsCache.java
@@ -125,16 +125,7 @@ public final class SuggestionsCache
   }
 
   // CachedSuggestions class is not a record because of a Frgaal bug leading to invalid compilation error.
-  public final static class CachedSuggestions {
-
-    private final LibraryName libraryName;
-    private final Suggestions suggestions;
-
-    public CachedSuggestions(LibraryName libraryName, Suggestions suggestions) {
-      this.libraryName = libraryName;
-      this.suggestions = suggestions;
-    }
-
+  public record CachedSuggestions(LibraryName libraryName, Suggestions suggestions) {
     public LibraryName getLibraryName() {
       return libraryName;
     }

I am seeing:

sbt:enso> buildEngineDistribution
[info] compiling 45 Scala sources and 191 Java sources to /enso/engine/runtime/target/scala-2.13/classes ...
[error] /enso/engine/runtime/src/main/java/org/enso/compiler/SuggestionsCache.java:128:17: not found: type java
[error]   public record CachedSuggestions(LibraryName libraryName, Suggestions suggestions) {
[error]                 ^
[error] one error found

That's a wild error. Reported to the frgaal project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is what I was seeing as well and the reason why in other cases I don't use the record. Thanks for reporting it with frgaal

name = libraryName.name,
version = libraryVersion.toString,
location = location.toFile
)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that the Api.LibraryLoaded should be enhanced with optional list of suggestions. However it looks like the proposal is to send a message to self and deserialize the suggestions later. Assuming the deserialization is instant - is there any benefit of sending the suggestions in a separate message?

@4e6 4e6 added the CI: No changelog needed Do not require a changelog entry for this PR. label Mar 6, 2023
@4e6 4e6 marked this pull request as ready for review March 6, 2023 16:35
@@ -1,6 +1,7 @@
package org.enso.languageserver.search

import org.enso.docs.generator.DocsGenerator
import org.enso.docs.sections.DocSectionsBuilder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably unnecessary import.

@4e6 4e6 added the CI: Ready to merge This PR is eligible for automatic merge label Mar 8, 2023
Copy link
Member

@radeusgd radeusgd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change in micro-distribution looks OK.

Copy link
Contributor

@hubertp hubertp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nits but overall looks ok

libraryLoaded.namespace,
libraryLoaded.name
)
System.err.println("Loaded library: " + libraryLoaded.name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks spurious

} yield {
val treeUpdates = treeResults.flatMap {
case QueryResult(ids, Api.SuggestionUpdate(suggestion, action)) =>
val verb = action.getClass.getSimpleName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be moved to the condition with the log using it?


@Override
protected byte[] metadata(String sourceDigest, String blobDigest, CachedSuggestions entry) {
var mapper = new ObjectMapper();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what I experienced. This causes major slowdowns, which is why I also changed it in #5791


@Override
protected byte[] metadata(String sourceDigest, String blobDigest, CachedSuggestions entry) {
var mapper = new ObjectMapper();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what I experienced. This causes major slowdowns, which is why I also changed it in #5791

}
}

// CachedSuggestions class is not a record because of a Frgaal bug leading to invalid compilation error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is what I was seeing as well and the reason why in other cases I don't use the record. Thanks for reporting it with frgaal

}

try {
val suggestions = new util.ArrayList[Suggestion]()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this rather be refactored to a separate method?

@mergify mergify bot merged commit 9397a6e into develop Mar 8, 2023
@mergify mergify bot deleted the wip/db/5068-pre-compute-suggestion-db-during-build-time branch March 8, 2023 12:37
@hubertp
Copy link
Contributor

hubertp commented Mar 9, 2023

@4e6 I think documentation needs to be updated as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: No changelog needed Do not require a changelog entry for this PR. CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pre-compute Suggestion DB during build time
4 participants