[release: nightly] Prune Versions when Verifying Modules Index (#1881)

clean module versions together with the
module suggestions
This commit is contained in:
Dmitry Bushev 2021-07-16 20:10:55 +03:00 committed by GitHub
parent 214495ad56
commit 4235d345aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 484 additions and 336 deletions

View File

@ -142,7 +142,7 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: LogLevel) {
lazy val bufferRegistry =
system.actorOf(
BufferRegistry.props(versionsRepo, fileManager, runtimeConnector),
BufferRegistry.props(fileManager, runtimeConnector),
"buffer-registry"
)

View File

@ -2,7 +2,7 @@ package org.enso.languageserver.search
import java.util.UUID
import akka.actor.{Actor, ActorRef, Props, Stash}
import akka.actor.{Actor, ActorRef, Props, Stash, Status}
import akka.pattern.{ask, pipe}
import com.typesafe.scalalogging.LazyLogging
import org.enso.languageserver.capability.CapabilityProtocol.{
@ -38,7 +38,7 @@ import org.enso.polyglot.Suggestion
import org.enso.polyglot.data.TypeGraph
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.searcher.data.QueryResult
import org.enso.searcher.{FileVersionsRepo, SuggestionsRepo}
import org.enso.searcher.{SuggestionsRepo, VersionsRepo}
import org.enso.text.ContentVersion
import org.enso.text.editing.model.Position
@ -80,6 +80,7 @@ import scala.util.{Failure, Success}
* @param config the server configuration
* @param contentRootManager the content root manager
* @param suggestionsRepo the suggestions repo
* @param versionsRepo the versions repo
* @param sessionRouter the session router
* @param runtimeConnector the runtime connector
*/
@ -87,7 +88,7 @@ final class SuggestionsHandler(
config: Config,
contentRootManager: ContentRootManager,
suggestionsRepo: SuggestionsRepo[Future],
fileVersionsRepo: FileVersionsRepo[Future],
versionsRepo: VersionsRepo[Future],
sessionRouter: ActorRef,
runtimeConnector: ActorRef
) extends Actor
@ -105,7 +106,7 @@ final class SuggestionsHandler(
"Starting suggestions handler from [{}, {}, {}].",
config,
suggestionsRepo,
fileVersionsRepo
versionsRepo
)
context.system.eventStream
.subscribe(self, classOf[Api.ExpressionUpdates])
@ -170,6 +171,13 @@ final class SuggestionsHandler(
logger.info("Initializing: got type graph response.")
tryInitialize(init.copy(typeGraph = Some(g)))
case Status.Failure(ex) =>
logger.error(
"Initialization failure [{}]. {}",
ex.getClass,
ex.getMessage
)
case _ => stash()
}
@ -179,16 +187,24 @@ final class SuggestionsHandler(
): Receive = {
case Api.Response(_, Api.VerifyModulesIndexResponse(toRemove)) =>
logger.info("Verifying: got verification response.")
suggestionsRepo
.removeModules(toRemove)
.map(_ => SuggestionsHandler.Verified)
.pipeTo(self)
val removeAction = for {
_ <- versionsRepo.remove(toRemove)
_ <- suggestionsRepo.removeModules(toRemove)
} yield SuggestionsHandler.Verified
removeAction.pipeTo(self)
case SuggestionsHandler.Verified =>
logger.info("Verified.")
context.become(initialized(projectName, graph, Set()))
unstashAll()
case Status.Failure(ex) =>
logger.error(
"Database verification failure [{}]. {}",
ex.getClass,
ex.getMessage
)
case _ =>
stash()
}
@ -214,7 +230,7 @@ final class SuggestionsHandler(
case msg: Api.SuggestionsDatabaseModuleUpdateNotification =>
val isVersionChanged =
fileVersionsRepo.getVersion(msg.file).map { digestOpt =>
versionsRepo.getVersion(msg.module).map { digestOpt =>
!digestOpt.map(ContentVersion(_)).contains(msg.version)
}
val applyUpdatesIfVersionChanged =
@ -234,7 +250,7 @@ final class SuggestionsHandler(
case Failure(ex) =>
logger.error(
"Error applying suggestion database updates [{}, {}]. {}",
MaskedPath(msg.file.toPath),
msg.module,
msg.version,
ex.getMessage
)
@ -366,7 +382,7 @@ final class SuggestionsHandler(
case InvalidateSuggestionsDatabase =>
val action = for {
_ <- suggestionsRepo.clean
_ <- fileVersionsRepo.clean
_ <- versionsRepo.clean
} yield SearchProtocol.InvalidateModulesIndex
val runtimeFailureMapper = RuntimeFailureMapper(contentRootManager)
@ -468,7 +484,7 @@ final class SuggestionsHandler(
for {
actionResults <- suggestionsRepo.applyActions(msg.actions)
(version, results) <- suggestionsRepo.applyTree(msg.updates)
_ <- fileVersionsRepo.setVersion(msg.file, msg.version.toDigest)
_ <- versionsRepo.setVersion(msg.module, msg.version.toDigest)
} yield {
val actionUpdates = actionResults.flatMap {
case QueryResult(ids, Api.SuggestionsDatabaseAction.Clean(_)) =>
@ -644,7 +660,7 @@ object SuggestionsHandler {
config: Config,
contentRootManager: ContentRootManager,
suggestionsRepo: SuggestionsRepo[Future],
fileVersionsRepo: FileVersionsRepo[Future],
fileVersionsRepo: VersionsRepo[Future],
sessionRouter: ActorRef,
runtimeConnector: ActorRef
): Props =

View File

@ -20,11 +20,8 @@ import org.enso.languageserver.text.TextProtocol.{
OpenFile,
SaveFile
}
import org.enso.searcher.FileVersionsRepo
import org.enso.text.ContentBasedVersioning
import scala.concurrent.Future
/** An actor that routes request regarding text editing to the right buffer.
* It creates a buffer actor, if a buffer doesn't exists.
*
@ -56,13 +53,11 @@ import scala.concurrent.Future
*
* }}}
*
* @param versionsRepo a repo containing versions of indexed files
* @param fileManager a file manager
* @param runtimeConnector a gateway to the runtime
* @param versionCalculator a content based version calculator
*/
class BufferRegistry(
versionsRepo: FileVersionsRepo[Future],
fileManager: ActorRef,
runtimeConnector: ActorRef
)(implicit
@ -102,7 +97,6 @@ class BufferRegistry(
context.actorOf(
CollaborativeBuffer.props(
path,
versionsRepo,
fileManager,
runtimeConnector
)
@ -157,19 +151,17 @@ object BufferRegistry {
/** Creates a configuration object used to create a [[BufferRegistry]]
*
* @param versionsRepo a repo containing versions of indexed files
* @param fileManager a file manager actor
* @param runtimeConnector a gateway to the runtime
* @param versionCalculator a content based version calculator
* @return a configuration object
*/
def props(
versionsRepo: FileVersionsRepo[Future],
fileManager: ActorRef,
runtimeConnector: ActorRef
)(implicit
versionCalculator: ContentBasedVersioning
): Props =
Props(new BufferRegistry(versionsRepo, fileManager, runtimeConnector))
Props(new BufferRegistry(fileManager, runtimeConnector))
}

View File

@ -1,7 +1,6 @@
package org.enso.languageserver.text
import akka.actor.{Actor, ActorRef, Cancellable, Props, Stash}
import akka.pattern.pipe
import cats.implicits._
import com.typesafe.scalalogging.LazyLogging
import org.enso.languageserver.capability.CapabilityProtocol._
@ -26,19 +25,16 @@ import org.enso.languageserver.text.CollaborativeBuffer.IOTimeout
import org.enso.languageserver.text.TextProtocol._
import org.enso.languageserver.util.UnhandledLogging
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.searcher.FileVersionsRepo
import org.enso.text.{ContentBasedVersioning, ContentVersion}
import org.enso.text.editing._
import org.enso.text.editing.model.TextEdit
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.language.postfixOps
/** An actor enabling multiple users edit collaboratively a file.
*
* @param bufferPath a path to a file
* @param versionsRepo a repo containing versions of indexed files
* @param fileManager a file manger actor
* @param runtimeConnector a gateway to the runtime
* @param timeout a request timeout
@ -46,7 +42,6 @@ import scala.language.postfixOps
*/
class CollaborativeBuffer(
bufferPath: Path,
versionsRepo: FileVersionsRepo[Future],
fileManager: ActorRef,
runtimeConnector: ActorRef,
timeout: FiniteDuration
@ -304,17 +299,9 @@ class CollaborativeBuffer(
originalSender ! OpenFileResponse(
Right(OpenFileResult(buffer, Some(cap)))
)
val currentVersion = versionCalculator.evalVersion(file.content)
versionsRepo
.setVersion(file.path, currentVersion.toDigest)
.map { prevDigestOpt =>
val prevVersionOpt = prevDigestOpt.map(ContentVersion(_))
val isIndexed = prevVersionOpt.contains(currentVersion)
Api.Request(
Api.OpenFileNotification(file.path, file.content, isIndexed)
)
}
.pipeTo(runtimeConnector)
runtimeConnector ! Api.Request(
Api.OpenFileNotification(file.path, file.content)
)
context.become(
collaborativeEditing(
buffer,
@ -425,7 +412,6 @@ object CollaborativeBuffer {
/** Creates a configuration object used to create a [[CollaborativeBuffer]]
*
* @param bufferPath a path to a file
* @param versionsRepo a repo containing versions of indexed files
* @param fileManager a file manager actor
* @param runtimeConnector a gateway to the runtime
* @param timeout a request timeout
@ -434,7 +420,6 @@ object CollaborativeBuffer {
*/
def props(
bufferPath: Path,
versionsRepo: FileVersionsRepo[Future],
fileManager: ActorRef,
runtimeConnector: ActorRef,
timeout: FiniteDuration = 10 seconds
@ -442,7 +427,6 @@ object CollaborativeBuffer {
Props(
new CollaborativeBuffer(
bufferPath,
versionsRepo,
fileManager,
runtimeConnector,
timeout

View File

@ -18,7 +18,7 @@ import org.enso.polyglot.Suggestion
import org.enso.polyglot.data.{Tree, TypeGraph}
import org.enso.polyglot.runtime.Runtime.Api
import org.enso.searcher.sql.{SqlDatabase, SqlSuggestionsRepo, SqlVersionsRepo}
import org.enso.searcher.{FileVersionsRepo, SuggestionsRepo}
import org.enso.searcher.{SuggestionsRepo, VersionsRepo}
import org.enso.testkit.RetrySpec
import org.enso.text.editing.model.Position
import org.enso.text.{ContentVersion, Sha3_224VersionCalculator}
@ -26,7 +26,6 @@ import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import java.io.File
import java.nio.file.Files
import java.util.UUID
import scala.concurrent.duration._
@ -54,6 +53,60 @@ class SuggestionsHandlerSpec
"SuggestionsHandler" should {
"prune stale modules" in withDbs { (config, suggestions, versions) =>
// setup database
val version1 = Array[Byte](1, 2, 3)
val version2 = Array[Byte](2, 3, 4)
val setupAction = for {
_ <- suggestions.insert(TestSuggestion.atom)
_ <- suggestions.insert(TestSuggestion.method)
_ <- versions.setVersion(TestSuggestion.atom.module, version1)
_ <- versions.setVersion(TestSuggestion.method.module, version2)
} yield ()
Await.ready(setupAction, Timeout)
withHandler(config, suggestions, versions) { (_, connector, handler) =>
// initialize
handler ! SuggestionsHandler.ProjectNameUpdated("Test")
handler ! InitializedEvent.TruffleContextInitialized
handler ! InitializedEvent.SuggestionsRepoInitialized
handler ! InitializedEvent.FileVersionsRepoInitialized
connector.receiveN(1)
handler ! Api.Response(
UUID.randomUUID(),
Api.GetTypeGraphResponse(buildTestTypeGraph)
)
connector.receiveN(1)
// prune atom module
handler ! Api.Response(
UUID.randomUUID(),
Api.VerifyModulesIndexResponse(Seq(TestSuggestion.atom.module))
)
// wait for initialization
handler ! AcquireCapability(
newJsonSession(UUID.randomUUID()),
CapabilityRegistration(ReceivesSuggestionsDatabaseUpdates())
)
expectMsg(CapabilityAcquired)
// check
val (_, entries) = Await.result(suggestions.getAll, Timeout)
entries.map(_.suggestion) should contain theSameElementsAs Seq(
TestSuggestion.method
)
val module1Version = Await.result(
versions.getVersion(TestSuggestion.atom.module),
Timeout
)
module1Version.isEmpty shouldBe true
val module2Version = Await.result(
versions.getVersion(TestSuggestion.method.module),
Timeout
)
module2Version.isEmpty shouldBe false
module2Version.get should contain theSameElementsInOrderAs version2
}
}
"subscribe to notification updates" taggedAs Retry in withDb {
(_, _, _, _, handler) =>
val clientId = UUID.randomUUID()
@ -78,7 +131,7 @@ class SuggestionsHandlerSpec
// receive updates
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion(""),
Vector(),
Tree.Root(Suggestions.all.toVector.map { suggestion =>
@ -123,7 +176,7 @@ class SuggestionsHandlerSpec
// receive updates
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion(""),
Vector(),
Tree.Root(
@ -217,7 +270,7 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion(""),
Vector(),
tree1
@ -291,7 +344,7 @@ class SuggestionsHandlerSpec
)
// update tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion("1"),
Vector(),
tree2
@ -380,7 +433,7 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion(""),
Vector(),
tree
@ -458,7 +511,7 @@ class SuggestionsHandlerSpec
// add tree
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion(""),
Vector(),
tree1
@ -482,7 +535,7 @@ class SuggestionsHandlerSpec
// clean module
handler ! Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
contentsVersion("1"),
Vector(Api.SuggestionsDatabaseAction.Clean(Suggestions.atom.module)),
Tree.Root(Vector())
@ -761,22 +814,38 @@ class SuggestionsHandlerSpec
sessionRouter: TestProbe,
runtimeConnector: TestProbe,
suggestionsRepo: SuggestionsRepo[Future],
fileVersionsRepo: FileVersionsRepo[Future]
fileVersionsRepo: VersionsRepo[Future]
): ActorRef = {
val contentRootManagerActor =
system.actorOf(ContentRootManagerActor.props(config))
val contentRootManagerWrapper: ContentRootManager =
new ContentRootManagerWrapper(config, contentRootManagerActor)
system.actorOf(
SuggestionsHandler.props(
config,
contentRootManagerWrapper,
suggestionsRepo,
fileVersionsRepo,
sessionRouter.ref,
runtimeConnector.ref
)
)
}
def newInitializedSuggestionsHandler(
config: Config,
sessionRouter: TestProbe,
runtimeConnector: TestProbe,
suggestionsRepo: SuggestionsRepo[Future],
fileVersionsRepo: VersionsRepo[Future]
): ActorRef = {
val handler =
system.actorOf(
SuggestionsHandler.props(
config,
contentRootManagerWrapper,
suggestionsRepo,
fileVersionsRepo,
sessionRouter.ref,
runtimeConnector.ref
)
newSuggestionsHandler(
config,
sessionRouter,
runtimeConnector,
suggestionsRepo,
fileVersionsRepo
)
handler ! SuggestionsHandler.ProjectNameUpdated("Test")
handler ! InitializedEvent.TruffleContextInitialized
@ -819,6 +888,69 @@ class SuggestionsHandlerSpec
def newJsonSession(clientId: UUID): JsonSession =
JsonSession(clientId, TestProbe().ref)
def withDbs(
test: (Config, SuggestionsRepo[Future], VersionsRepo[Future]) => Any
): Unit = {
val testContentRoot = Files.createTempDirectory(null).toRealPath()
sys.addShutdownHook(FileUtils.deleteQuietly(testContentRoot.toFile))
val config = newConfig(
ContentRootWithFile(
ContentRoot.Project(UUID.randomUUID()),
testContentRoot.toFile
)
)
val sqlDatabase = SqlDatabase(config.directories.suggestionsDatabaseFile)
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)
val suggestionsInit = suggestionsRepo.init
val versionsInit = versionsRepo.init
suggestionsInit.onComplete {
case Success(()) =>
system.eventStream.publish(InitializedEvent.SuggestionsRepoInitialized)
case Failure(ex) =>
system.log.error(ex, "Failed to initialize Suggestions repo")
}
versionsInit.onComplete {
case Success(()) =>
system.eventStream.publish(InitializedEvent.FileVersionsRepoInitialized)
case Failure(ex) =>
system.log.error(ex, "Failed to initialize FileVersions repo")
}
Await.ready(suggestionsInit, Timeout)
Await.ready(versionsInit, Timeout)
try test(config, suggestionsRepo, versionsRepo)
finally {
versionsRepo.close()
suggestionsRepo.close()
}
}
def withHandler(
config: Config,
suggestionsRepo: SuggestionsRepo[Future],
versionsRepo: VersionsRepo[Future]
)(
test: (TestProbe, TestProbe, ActorRef) => Any
): Unit = {
val router = TestProbe("session-router")
val connector = TestProbe("runtime-connector")
val handler = newSuggestionsHandler(
config,
router,
connector,
suggestionsRepo,
versionsRepo
)
try test(router, connector, handler)
finally {
system.stop(handler)
}
}
def withDb(
test: (
Config,
@ -836,9 +968,9 @@ class SuggestionsHandlerSpec
testContentRoot.toFile
)
)
val router = TestProbe("session-router")
val connector = TestProbe("runtime-connector")
val sqlDatabase = SqlDatabase( config.directories.suggestionsDatabaseFile)
val router = TestProbe("session-router")
val connector = TestProbe("runtime-connector")
val sqlDatabase = SqlDatabase(config.directories.suggestionsDatabaseFile)
val suggestionsRepo = new SqlSuggestionsRepo(sqlDatabase)
val versionsRepo = new SqlVersionsRepo(sqlDatabase)
@ -855,7 +987,7 @@ class SuggestionsHandlerSpec
system.log.error(ex, "Failed to initialize FileVersions repo")
}
val handler = newSuggestionsHandler(
val handler = newInitializedSuggestionsHandler(
config,
router,
connector,
@ -870,4 +1002,33 @@ class SuggestionsHandlerSpec
}
}
object TestSuggestion {
val atom: Suggestion.Atom =
Suggestion.Atom(
externalId = None,
module = "Test.Pair",
name = "Pair",
arguments = Seq(
Suggestion.Argument("a", "Any", false, false, None),
Suggestion.Argument("b", "Any", false, false, None)
),
returnType = "Pair",
documentation = Some("Awesome"),
documentationHtml = Some("")
)
val method: Suggestion.Method =
Suggestion.Method(
externalId = Some(UUID.randomUUID()),
module = "Test.Main",
name = "main",
arguments = Seq(),
selfType = "Test.Main",
returnType = "IO",
documentation = None,
documentationHtml = None
)
}
}

View File

@ -138,7 +138,6 @@ class BaseServerTest
val bufferRegistry =
system.actorOf(
BufferRegistry.props(
versionsRepo,
fileManager,
runtimeConnectorProbe.ref
)(

View File

@ -88,7 +88,7 @@ class FileNotificationsTest extends BaseServerTest with FlakySpec {
// 4
runtimeConnectorProbe.expectMsg(
Api.Request(
Api.OpenFileNotification(file("foo.txt"), "123456789", false)
Api.OpenFileNotification(file("foo.txt"), "123456789")
)
)

View File

@ -1,7 +1,5 @@
package org.enso.languageserver.websocket.json
import java.io.File
import io.circe.literal._
import org.enso.languageserver.search.Suggestions
import org.enso.languageserver.websocket.json.{SearchJsonMessages => json}
@ -22,7 +20,7 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
// add atom
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
versionCalculator.evalVersion("1"),
Vector(),
Tree.Root(
@ -71,7 +69,7 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
// add method
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
versionCalculator.evalVersion("2"),
Vector(),
Tree.Root(
@ -139,7 +137,7 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
// add function
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
versionCalculator.evalVersion("3"),
Vector(),
Tree.Root(
@ -229,7 +227,7 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
// add local
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
versionCalculator.evalVersion("4"),
Vector(),
Tree.Root(
@ -427,7 +425,7 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
// update items
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
versionCalculator.evalVersion("5"),
Vector(),
Tree.Root(
@ -545,7 +543,7 @@ class SuggestionsHandlerEventsTest extends BaseServerTest with FlakySpec {
// remove items
system.eventStream.publish(
Api.SuggestionsDatabaseModuleUpdateNotification(
new File("/tmp/foo"),
"Foo.Main",
versionCalculator.evalVersion("6"),
Vector(Api.SuggestionsDatabaseAction.Clean(Suggestions.atom.module)),
Tree.Root(Vector())

View File

@ -1104,12 +1104,10 @@ object Runtime {
*
* @param path the file being moved to memory.
* @param contents the current file contents.
* @param isIndexed the flag specifying whether the file is indexed
*/
case class OpenFileNotification(
path: File,
contents: String,
isIndexed: Boolean
contents: String
) extends ApiRequest
with ToLogString {
@ -1118,7 +1116,6 @@ object Runtime {
"OpenFileNotification(" +
s"path=${MaskedPath(path.toPath).toLogString(shouldMask)}," +
s"contents=${MaskedString(contents).toLogString(shouldMask)}," +
s"isIndexed=$isIndexed" +
")"
}
@ -1260,13 +1257,13 @@ object Runtime {
/** A notification about the changes in the suggestions database.
*
* @param file the module file path
* @param module the module name
* @param version the version of the module
* @param actions the list of actions to apply to the suggestions database
* @param updates the list of suggestions extracted from module
*/
case class SuggestionsDatabaseModuleUpdateNotification(
file: File,
module: String,
version: ContentVersion,
actions: Vector[SuggestionsDatabaseAction],
updates: Tree[SuggestionUpdate]
@ -1276,7 +1273,7 @@ object Runtime {
/** @inheritdoc */
override def toLogString(shouldMask: Boolean): String =
"SuggestionsDatabaseModuleUpdateNotification(" +
s"file=${MaskedPath(file.toPath).toLogString(shouldMask)}," +
s"module=$module," +
s"version=$version," +
s"actions=$actions," +
s"updates=${updates.map(_.toLogString(shouldMask))}" +

View File

@ -238,7 +238,7 @@ public class ExecutionService {
* @param path the module path.
* @param contents the sources to use for it.
*/
public void setModuleSources(File path, String contents, boolean isIndexed) {
public void setModuleSources(File path, String contents) {
Optional<Module> module = context.getModuleForFile(path);
if (module.isEmpty()) {
module = context.createModuleForFile(path);
@ -246,7 +246,6 @@ public class ExecutionService {
module.ifPresent(
mod -> {
mod.setLiteralSource(contents);
mod.setIndexed(isIndexed);
});
}

View File

@ -22,8 +22,7 @@ class OpenFileCmd(request: Api.OpenFileNotification) extends Command(None) {
try {
ctx.executionService.setModuleSources(
request.path,
request.contents,
request.isIndexed
request.contents
)
} finally {
ctx.locking.releaseReadCompilationLock()

View File

@ -157,7 +157,7 @@ class EnsureCompiledJob(protected val files: Iterable[File])
.filter(isSuggestionGlobal)
val version = ctx.versioning.evalVersion(module.getLiteralSource.toString)
val notification = Api.SuggestionsDatabaseModuleUpdateNotification(
file = getIndexingPath(module),
module = moduleName.toString,
version = version,
actions =
Vector(Api.SuggestionsDatabaseAction.Clean(moduleName.toString)),
@ -185,7 +185,7 @@ class EnsureCompiledJob(protected val files: Iterable[File])
val diff = SuggestionDiff
.compute(prevSuggestions, newSuggestions)
val notification = Api.SuggestionsDatabaseModuleUpdateNotification(
file = new File(module.getPath),
module = moduleName.toString,
version = version,
actions = Vector(),
updates = diff
@ -198,7 +198,7 @@ class EnsureCompiledJob(protected val files: Iterable[File])
SuggestionBuilder(module.getLiteralSource)
.build(moduleName, module.getIr)
val notification = Api.SuggestionsDatabaseModuleUpdateNotification(
file = new File(module.getPath),
module = moduleName.toString,
version = version,
actions =
Vector(Api.SuggestionsDatabaseAction.Clean(moduleName.toString)),
@ -441,17 +441,6 @@ class EnsureCompiledJob(protected val files: Iterable[File])
ctx: RuntimeContext
): Iterable[Module] =
ctx.executionService.getContext.getTopScope.getModules.asScala
/** Get the module path for suggestions database indexing.
*
* If the module is synthetic (i.e. Builtins), uses its name as a path.
*/
private def getIndexingPath(module: Module): File =
if (module.getPath eq null) {
new File(s"/${module.getName}")
} else
new File(module.getPath)
}
object EnsureCompiledJob {

View File

@ -167,7 +167,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -251,7 +251,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -330,7 +330,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -397,7 +397,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -480,7 +480,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -554,7 +554,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -694,7 +694,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -783,7 +783,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -869,7 +869,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -968,7 +968,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1084,7 +1084,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1207,7 +1207,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1315,7 +1315,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1410,7 +1410,7 @@ class RuntimeErrorsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None

View File

@ -152,7 +152,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -201,7 +201,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -258,7 +258,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -318,7 +318,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -377,7 +377,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -434,7 +434,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -493,7 +493,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -558,7 +558,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -618,7 +618,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -675,7 +675,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -737,7 +737,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -799,7 +799,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -859,7 +859,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -931,7 +931,7 @@ class RuntimeInstrumentTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None

View File

@ -365,7 +365,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -473,7 +473,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -575,10 +575,10 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
context.send(Api.Request(Api.OpenFileNotification(aFile, aCode, true)))
context.send(Api.Request(Api.OpenFileNotification(aFile, aCode)))
context.receiveNone shouldEqual None
// push main
@ -661,7 +661,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -720,7 +720,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -779,7 +779,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -840,7 +840,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -901,7 +901,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -969,7 +969,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1067,7 +1067,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1148,7 +1148,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1236,7 +1236,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1434,7 +1434,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1627,7 +1627,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1673,7 +1673,7 @@ class RuntimeServerTest
val mainFile = context.writeMain(code)
// Open the new file
context.send(Api.Request(Api.OpenFileNotification(mainFile, code, true)))
context.send(Api.Request(Api.OpenFileNotification(mainFile, code)))
context.receiveNone shouldEqual None
context.consumeOut shouldEqual List()
@ -1739,7 +1739,7 @@ class RuntimeServerTest
val mainFile = context.writeMain(code)
// Open the new file
context.send(Api.Request(Api.OpenFileNotification(mainFile, code, true)))
context.send(Api.Request(Api.OpenFileNotification(mainFile, code)))
context.receiveNone shouldEqual None
// Push new item on the stack to trigger the re-execution
@ -1798,7 +1798,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, context.Main.code, true))
Api.Request(Api.OpenFileNotification(mainFile, context.Main.code))
)
context.receiveNone shouldEqual None
@ -1874,7 +1874,7 @@ class RuntimeServerTest
val mainFile = context.writeMain(code)
// Open the new file
context.send(Api.Request(Api.OpenFileNotification(mainFile, code, true)))
context.send(Api.Request(Api.OpenFileNotification(mainFile, code)))
context.receiveNone shouldEqual None
context.consumeOut shouldEqual List()
@ -1951,7 +1951,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1997,7 +1997,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2049,7 +2049,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2102,7 +2102,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2146,7 +2146,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2197,7 +2197,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2255,7 +2255,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2323,7 +2323,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2399,7 +2399,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2477,7 +2477,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2556,7 +2556,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2650,7 +2650,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2711,7 +2711,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2771,7 +2771,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2835,7 +2835,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2899,7 +2899,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -2959,7 +2959,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -3008,7 +3008,7 @@ class RuntimeServerTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -3055,7 +3055,7 @@ class RuntimeServerTest
// open file
context.send(
Api.Request(
Api.OpenFileNotification(mainFile, contents, isIndexed = true)
Api.OpenFileNotification(mainFile, contents)
)
)
context.receiveNone shouldEqual None

View File

@ -165,7 +165,7 @@ class RuntimeStdlibTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveOne shouldEqual None
@ -208,8 +208,8 @@ class RuntimeStdlibTest
val stdlibSuggestions = responses.collect {
case Api.Response(
None,
Api.SuggestionsDatabaseModuleUpdateNotification(file, _, as, xs)
) if file.getPath.contains("Vector") =>
Api.SuggestionsDatabaseModuleUpdateNotification(module, _, as, xs)
) if module.contains("Vector") =>
(xs.nonEmpty || as.nonEmpty) shouldBe true
xs.toVector.head.suggestion.module shouldEqual "Standard.Base.Data.Vector"
}
@ -219,8 +219,8 @@ class RuntimeStdlibTest
val builtinsSuggestions = responses.collect {
case Api.Response(
None,
Api.SuggestionsDatabaseModuleUpdateNotification(file, _, as, xs)
) if file.getPath.contains("Builtins") =>
Api.SuggestionsDatabaseModuleUpdateNotification(module, _, as, xs)
) if module.contains("Builtins") =>
(xs.nonEmpty || as.nonEmpty) shouldBe true
}
builtinsSuggestions.length shouldBe 1

View File

@ -138,7 +138,7 @@ class RuntimeSuggestionUpdatesTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, code, false))
Api.Request(Api.OpenFileNotification(mainFile, code))
)
context.receiveNone shouldEqual None
@ -160,7 +160,7 @@ class RuntimeSuggestionUpdatesTest
Api.Response(requestId, Api.PushContextResponse(contextId)),
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = version,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
updates = Tree.Root(
@ -230,7 +230,7 @@ class RuntimeSuggestionUpdatesTest
context.receive(2) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = contentsVersion(
"""from Standard.Builtins import all
|
@ -313,7 +313,7 @@ class RuntimeSuggestionUpdatesTest
context.receive(2) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = contentsVersion(
"""from Standard.Builtins import all
|
@ -416,7 +416,7 @@ class RuntimeSuggestionUpdatesTest
context.receive(2) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = contentsVersion(
"""from Standard.Builtins import all
|
@ -528,7 +528,7 @@ class RuntimeSuggestionUpdatesTest
context.receive(2) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = contentsVersion(
"""from Standard.Builtins import all
|
@ -668,7 +668,7 @@ class RuntimeSuggestionUpdatesTest
context.receive(2) should contain theSameElementsAs Seq(
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = contentsVersion(
"""from Standard.Builtins import all
|
@ -764,7 +764,7 @@ class RuntimeSuggestionUpdatesTest
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, false))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -786,7 +786,7 @@ class RuntimeSuggestionUpdatesTest
Api.Response(requestId, Api.PushContextResponse(contextId)),
Api.Response(
Api.SuggestionsDatabaseModuleUpdateNotification(
file = mainFile,
module = moduleName,
version = version,
actions = Vector(Api.SuggestionsDatabaseAction.Clean(moduleName)),
updates = Tree.Root(

View File

@ -288,8 +288,7 @@ class RuntimeVisualisationsTest
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
@ -306,7 +305,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -402,8 +401,7 @@ class RuntimeVisualisationsTest
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
@ -420,7 +418,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -536,14 +534,13 @@ class RuntimeVisualisationsTest
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
context.receiveNone shouldEqual None
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -659,14 +656,13 @@ class RuntimeVisualisationsTest
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
context.receiveNone shouldEqual None
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -774,15 +770,14 @@ class RuntimeVisualisationsTest
// open files
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
context.send(
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
@ -896,15 +891,14 @@ class RuntimeVisualisationsTest
// open files
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
context.send(
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
@ -1038,14 +1032,13 @@ class RuntimeVisualisationsTest
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
context.receiveNone shouldEqual None
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1137,15 +1130,14 @@ class RuntimeVisualisationsTest
// open files
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
context.send(
Api.Request(
Api.OpenFileNotification(
visualisationFile,
context.Visualisation.code,
true
context.Visualisation.code
)
)
)
@ -1281,7 +1273,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1341,7 +1333,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1429,7 +1421,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1503,7 +1495,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
@ -1591,8 +1583,7 @@ class RuntimeVisualisationsTest
Api.Request(
Api.OpenFileNotification(
visualisationFile,
visualisationCode,
true
visualisationCode
)
)
)
@ -1609,7 +1600,7 @@ class RuntimeVisualisationsTest
// Open the new file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents, true))
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None

View File

@ -1,48 +0,0 @@
package org.enso.searcher
import java.io.File
/** The object for accessing the database containing the file versions. */
trait FileVersionsRepo[F[_]] {
/** Initialize the repo. */
def init: F[Unit]
/** Get the file version.
*
* @param file the file path
* @return the version digest
*/
def getVersion(file: File): F[Option[Array[Byte]]]
/** Set the file version.
*
* @param file the file path
* @param digest the version digest
* @return previously recorded file version
*/
def setVersion(file: File, digest: Array[Byte]): F[Option[Array[Byte]]]
/** Update the version if it differs from the recorded version.
*
* @param file the file path
* @param digest the version digest
* @return `true` if the version has been updated
*/
def updateVersion(file: File, digest: Array[Byte]): F[Boolean]
/** Update the versions in batch.
*
* @param versions files with corresponding digests
*/
def updateVersions(versions: Seq[(File, Array[Byte])]): F[Unit]
/** Remove the version record.
*
* @param file the file path
*/
def remove(file: File): F[Unit]
/** Clean the repo. */
def clean: F[Unit]
}

View File

@ -0,0 +1,52 @@
package org.enso.searcher
/** The object for accessing the database containing the module versions. */
trait VersionsRepo[F[_]] {
/** Initialize the repo. */
def init: F[Unit]
/** Get the module version.
*
* @param module the module name
* @return the version digest
*/
def getVersion(module: String): F[Option[Array[Byte]]]
/** Set the module version.
*
* @param module the module name
* @param digest the version digest
* @return previously recorded version
*/
def setVersion(module: String, digest: Array[Byte]): F[Option[Array[Byte]]]
/** Update the version if it differs from the recorded version.
*
* @param module the module name
* @param digest the version digest
* @return `true` if the version has been updated
*/
def updateVersion(module: String, digest: Array[Byte]): F[Boolean]
/** Update the versions in batch.
*
* @param versions files with corresponding digests
*/
def updateVersions(versions: Seq[(String, Array[Byte])]): F[Unit]
/** Remove the version record.
*
* @param module the module name
*/
def remove(module: String): F[Unit]
/** Remove a list of version records.
*
* @param modules the list of modules to remove
*/
def remove(modules: Seq[String]): F[Unit]
/** Clean the repo. */
def clean: F[Unit]
}

View File

@ -202,7 +202,7 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
} yield ()
val tables: Seq[TableQuery[RelationalTable[_]]] =
Seq(Suggestions, Arguments, SuggestionsVersions, SchemaVersion)
Seq(Suggestions, Arguments, SuggestionsVersion, SchemaVersion)
.asInstanceOf[Seq[TableQuery[RelationalTable[_]]]]
val initSchemas =
for {
@ -222,7 +222,7 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
for {
_ <- Suggestions.delete
_ <- Arguments.delete
_ <- SuggestionsVersions.delete
_ <- SuggestionsVersion.delete
} yield ()
}
@ -758,17 +758,17 @@ final class SqlSuggestionsRepo(val db: SqlDatabase)(implicit
/** The query to get current version of the repo. */
private def currentVersionQuery: DBIO[Long] = {
for {
versionOpt <- SuggestionsVersions.result.headOption
versionOpt <- SuggestionsVersion.result.headOption
} yield versionOpt.flatMap(_.id).getOrElse(0L)
}
/** The query to increment the current version of the repo. */
private def incrementVersionQuery: DBIO[Long] = {
val incrementQuery = for {
version <- SuggestionsVersions.returning(
SuggestionsVersions.map(_.id)
version <- SuggestionsVersion.returning(
SuggestionsVersion.map(_.id)
) += SuggestionsVersionRow(None)
_ <- SuggestionsVersions.filterNot(_.id === version).delete
_ <- SuggestionsVersion.filterNot(_.id === version).delete
} yield version
incrementQuery
}

View File

@ -1,45 +1,51 @@
package org.enso.searcher.sql
import java.io.File
import java.util
import org.enso.searcher.FileVersionsRepo
import org.enso.searcher.VersionsRepo
import slick.jdbc.SQLiteProfile.api._
import slick.jdbc.meta.MTable
import scala.concurrent.{ExecutionContext, Future}
final class SqlVersionsRepo(db: SqlDatabase)(implicit ec: ExecutionContext)
extends FileVersionsRepo[Future] {
extends VersionsRepo[Future] {
/** Initialize the repo. */
override def init: Future[Unit] =
db.run(initQuery)
/** @inheritdoc */
override def getVersion(file: File): Future[Option[Array[Byte]]] =
db.run(getVersionQuery(file))
override def getVersion(module: String): Future[Option[Array[Byte]]] =
db.run(getVersionQuery(module))
/** @inheritdoc */
override def setVersion(
file: File,
module: String,
digest: Array[Byte]
): Future[Option[Array[Byte]]] =
db.run(setVersionQuery(file, digest))
db.run(setVersionQuery(module, digest))
/** @inheritdoc */
override def updateVersion(file: File, digest: Array[Byte]): Future[Boolean] =
db.run(updateVersionQuery(file, digest))
override def updateVersion(
module: String,
digest: Array[Byte]
): Future[Boolean] =
db.run(updateVersionQuery(module, digest))
/** @inheritdoc */
override def updateVersions(
versions: Seq[(File, Array[Byte])]
versions: Seq[(String, Array[Byte])]
): Future[Unit] =
db.run(updateVersionsQuery(versions))
/** @inheritdoc */
override def remove(file: File): Future[Unit] =
db.run(removeQuery(file))
override def remove(module: String): Future[Unit] =
db.run(removeQuery(module))
/** @inheritdoc */
override def remove(modules: Seq[String]): Future[Unit] =
db.run(removeModulesQuery(modules))
/** @inheritdoc */
override def clean: Future[Unit] =
@ -51,7 +57,7 @@ final class SqlVersionsRepo(db: SqlDatabase)(implicit ec: ExecutionContext)
/** The query to initialize the repo. */
private def initQuery: DBIO[Unit] = {
val table = FileVersions
val table = ModuleVersions
for {
tables <- MTable.getTables(table.shaped.value.tableName)
_ <- if (tables.isEmpty) table.schema.create else DBIO.successful(())
@ -60,54 +66,54 @@ final class SqlVersionsRepo(db: SqlDatabase)(implicit ec: ExecutionContext)
/** The query to clean the repo. */
private def cleanQuery: DBIO[Unit] =
FileVersions.delete >> DBIO.successful(())
ModuleVersions.delete >> DBIO.successful(())
/** The query to get the version digest of the file.
*
* @param file the file path
* @param module the module name
* @return the version digest
*/
private def getVersionQuery(file: File): DBIO[Option[Array[Byte]]] = {
private def getVersionQuery(module: String): DBIO[Option[Array[Byte]]] = {
val query = for {
row <- FileVersions
if row.path === file.toString
row <- ModuleVersions
if row.module === module
} yield row.digest
query.result.headOption
}
/** The query to set the version digest of the file.
*
* @param file the file path
* @param module the module name
* @param version the version digest
* @return the previously recorded vile version
*/
private def setVersionQuery(
file: File,
module: String,
version: Array[Byte]
): DBIO[Option[Array[Byte]]] = {
val upsertQuery = FileVersions
.insertOrUpdate(FileVersionRow(file.toString, version))
val upsertQuery =
ModuleVersions.insertOrUpdate(ModuleVersionRow(module, version))
for {
version <- getVersionQuery(file)
version <- getVersionQuery(module)
_ <- upsertQuery
} yield version
}
/** The query to update the version if it differs from the recorded version.
*
* @param file the file path
* @param module the module name
* @param version the version digest
* @return `true` if the version has been updated
*/
private def updateVersionQuery(
file: File,
module: String,
version: Array[Byte]
): DBIO[Boolean] =
for {
repoVersion <- getVersionQuery(file)
versionsEquals = repoVersion.fold(false)(compareVersions(_, version))
moduleVersion <- getVersionQuery(module)
versionsEquals = moduleVersion.fold(false)(compareVersions(_, version))
_ <-
if (!versionsEquals) setVersionQuery(file, version)
if (!versionsEquals) setVersionQuery(module, version)
else DBIO.successful(None)
} yield !versionsEquals
@ -116,11 +122,11 @@ final class SqlVersionsRepo(db: SqlDatabase)(implicit ec: ExecutionContext)
* @param versions files with corresponding digests
*/
private def updateVersionsQuery(
versions: Seq[(File, Array[Byte])]
versions: Seq[(String, Array[Byte])]
): DBIO[Unit] =
if (versions.nonEmpty) {
def upsertQuery(file: File, version: Array[Byte]) = FileVersions
.insertOrUpdate(FileVersionRow(file.toString, version))
def upsertQuery(module: String, version: Array[Byte]) =
ModuleVersions.insertOrUpdate(ModuleVersionRow(module, version))
DBIO.sequence(versions.map(Function.tupled(upsertQuery))) >>
DBIO.successful(())
} else {
@ -129,16 +135,29 @@ final class SqlVersionsRepo(db: SqlDatabase)(implicit ec: ExecutionContext)
/** The query to remove the version record.
*
* @param file the file path
* @param module the module name
*/
private def removeQuery(file: File): DBIO[Unit] = {
private def removeQuery(module: String): DBIO[Unit] = {
val query = for {
row <- FileVersions
if row.path === file.toString
row <- ModuleVersions
if row.module === module
} yield row
query.delete >> DBIO.successful(())
}
/** The query to remove multiple module versions.
*
* @param modules the list of module names
*/
private def removeModulesQuery(modules: Seq[String]): DBIO[Unit] = {
val deleteQuery = ModuleVersions
.filter(_.module.inSet(modules))
.delete
for {
_ <- deleteQuery
} yield ()
}
private def compareVersions(v1: Array[Byte], v2: Array[Byte]): Boolean =
util.Arrays.equals(v1, v2)

View File

@ -74,10 +74,10 @@ case class SchemaVersionRow(id: Option[Long])
/** A row in the file_versions table
*
* @param path the file path
* @param module the module name
* @param digest the file version
*/
case class FileVersionRow(path: String, digest: Array[Byte])
case class ModuleVersionRow(module: String, digest: Array[Byte])
/** The type of a suggestion. */
object SuggestionKind {
@ -215,15 +215,16 @@ final class SuggestionsTable(tag: Tag)
)
}
/** The schema of the file_versions table. */
/** The schema of the module_versions table. */
@nowarn("msg=multiarg infix syntax")
final class FileVersionsTable(tag: Tag)
extends Table[FileVersionRow](tag, "file_versions") {
final class ModuleVersionsTable(tag: Tag)
extends Table[ModuleVersionRow](tag, "module_versions") {
def path = column[String]("path", O.PrimaryKey)
def module = column[String]("module", O.PrimaryKey)
def digest = column[Array[Byte]]("digest")
def * = (path, digest) <> (FileVersionRow.tupled, FileVersionRow.unapply)
def * =
(module, digest) <> (ModuleVersionRow.tupled, ModuleVersionRow.unapply)
}
/** The schema of the suggestions_version table. */
@ -250,12 +251,12 @@ object Arguments extends TableQuery(new ArgumentsTable(_))
object Suggestions extends TableQuery(new SuggestionsTable(_))
object FileVersions extends TableQuery(new FileVersionsTable(_))
object ModuleVersions extends TableQuery(new ModuleVersionsTable(_))
object SuggestionsVersions extends TableQuery(new SuggestionsVersionTable(_))
object SuggestionsVersion extends TableQuery(new SuggestionsVersionTable(_))
object SchemaVersion extends TableQuery(new SchemaVersionTable(_)) {
/** The current schema version. */
val CurrentVersion: Long = 2
val CurrentVersion: Long = 3
}

View File

@ -1,6 +1,5 @@
package org.enso.searcher.sql
import java.io.File
import java.nio.file.{Files, Path}
import java.util
@ -13,7 +12,7 @@ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.util.Random
class FileVersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
class VersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
val Timeout: FiniteDuration = 20.seconds
@ -49,12 +48,12 @@ class FileVersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
}
"insert digest" taggedAs Retry in withRepo { repo =>
val file = new File("/foo/bar")
val module = "Foo.Bar"
val digest = nextDigest()
val action =
for {
v1 <- repo.setVersion(file, digest)
v2 <- repo.getVersion(file)
v1 <- repo.setVersion(module, digest)
v2 <- repo.getVersion(module)
} yield (v1, v2)
val (v1, v2) = Await.result(action, Timeout)
@ -64,14 +63,14 @@ class FileVersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
}
"set digest" taggedAs Retry in withRepo { repo =>
val file = new File("/foo/bar")
val module = "Foo.Bar"
val digest1 = nextDigest()
val digest2 = nextDigest()
val action =
for {
v1 <- repo.setVersion(file, digest1)
v2 <- repo.setVersion(file, digest2)
v3 <- repo.getVersion(file)
v1 <- repo.setVersion(module, digest1)
v2 <- repo.setVersion(module, digest2)
v3 <- repo.getVersion(module)
} yield (v1, v2, v3)
val (v1, v2, v3) = Await.result(action, Timeout)
@ -83,18 +82,18 @@ class FileVersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
}
"update digest" taggedAs Retry in withRepo { repo =>
val file = new File("/foo/bazz")
val module = "Foo.Bar"
val digest1 = nextDigest()
val digest2 = nextDigest()
val digest3 = nextDigest()
val action =
for {
b1 <- repo.updateVersion(file, digest1)
v2 <- repo.setVersion(file, digest2)
b2 <- repo.updateVersion(file, digest2)
b3 <- repo.updateVersion(file, digest3)
b4 <- repo.updateVersion(file, digest3)
v3 <- repo.getVersion(file)
b1 <- repo.updateVersion(module, digest1)
v2 <- repo.setVersion(module, digest2)
b2 <- repo.updateVersion(module, digest2)
b3 <- repo.updateVersion(module, digest3)
b4 <- repo.updateVersion(module, digest3)
v3 <- repo.getVersion(module)
} yield (v2, v3, b1, b2, b3, b4)
val (v2, v3, b1, b2, b3, b4) = Await.result(action, Timeout)
@ -109,18 +108,18 @@ class FileVersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
}
"batch update digest" taggedAs Retry in withRepo { repo =>
val file1 = new File("/foo/1")
val file2 = new File("/foo/2")
val module1 = "Foo.Bar"
val module2 = "Foo.Baz"
val digest0 = nextDigest()
val digest1 = nextDigest()
val digest2 = nextDigest()
val input = Seq(file1 -> digest1, file2 -> digest2)
val input = Seq(module1 -> digest1, module2 -> digest2)
val action =
for {
_ <- repo.setVersion(file1, digest0)
_ <- repo.setVersion(module1, digest0)
_ <- repo.updateVersions(input)
v1 <- repo.getVersion(file1)
v2 <- repo.getVersion(file2)
v1 <- repo.getVersion(module1)
v2 <- repo.getVersion(module2)
} yield (v1, v2)
val (v1, v2) = Await.result(action, Timeout)
@ -131,13 +130,13 @@ class FileVersionsRepoTest extends AnyWordSpec with Matchers with RetrySpec {
}
"delete digest" taggedAs Retry in withRepo { repo =>
val file = new File("/foo/bar")
val module = "Foo.Bar"
val digest = nextDigest()
val action =
for {
v1 <- repo.setVersion(file, digest)
_ <- repo.remove(file)
v2 <- repo.getVersion(file)
v1 <- repo.setVersion(module, digest)
_ <- repo.remove(module)
v2 <- repo.getVersion(module)
} yield (v1, v2)
val (v1, v2) = Await.result(action, Timeout)