-
Notifications
You must be signed in to change notification settings - Fork 337
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
improvement: Only reindex workspace on onBuildTargetChanged #5737
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -401,7 +401,7 @@ class MetalsLspService( | |
worksheetProvider.onBuildTargetDidCompile(target) | ||
}, | ||
onBuildTargetDidChangeFunc = params => { | ||
maybeQuickConnectToBuildServer(params) | ||
onBuildTargetChanges(params) | ||
}, | ||
bspErrorHandler, | ||
) | ||
|
@@ -1966,11 +1966,19 @@ class MetalsLspService( | |
buildTool.version, | ||
) | ||
|
||
def supportedBuildTool(): Future[Option[BuildTool]] = { | ||
def supportedBuildTool(): Future[Option[BuildTool.Found]] = { | ||
def isCompatibleVersion(buildTool: BuildTool) = { | ||
val isCompatibleVersion = this.isCompatibleVersion(buildTool) | ||
if (isCompatibleVersion) { | ||
Some(buildTool) | ||
buildTool.digest(folder) match { | ||
case Some(digest) => | ||
Some(BuildTool.Found(buildTool, digest)) | ||
case None => | ||
scribe.warn( | ||
s"Could not calculate checksum for ${buildTool.executableName} in $folder" | ||
) | ||
None | ||
} | ||
} else { | ||
scribe.warn(s"Unsupported $buildTool version ${buildTool.version}") | ||
languageClient.showMessage( | ||
|
@@ -1991,10 +1999,12 @@ class MetalsLspService( | |
} | ||
case buildTools => | ||
for { | ||
Some(buildTool) <- buildToolSelector.checkForChosenBuildTool( | ||
buildTool <- buildToolSelector.checkForChosenBuildTool( | ||
buildTools | ||
) | ||
} yield isCompatibleVersion(buildTool) | ||
} yield { | ||
buildTool.flatMap(isCompatibleVersion) | ||
} | ||
} | ||
} | ||
|
||
|
@@ -2008,38 +2018,32 @@ class MetalsLspService( | |
_ == BloopServers.name | ||
) | ||
buildChange <- possibleBuildTool match { | ||
case Some(buildTool) => | ||
(buildTool.digest(folder), buildTool) match { | ||
case (None, _) => | ||
scribe.warn(s"Skipping build import, no checksum.") | ||
Future.successful(BuildChange.None) | ||
case (Some(_), buildTool: ScalaCliBuildTool) | ||
if chosenBuildServer.isEmpty => | ||
tables.buildServers.chooseServer(ScalaCliBuildTool.name) | ||
val scalaCliBspConfigExists = | ||
ScalaCliBuildTool.pathsToScalaCliBsp(folder).exists(_.isFile) | ||
if (scalaCliBspConfigExists) Future.successful(BuildChange.None) | ||
else | ||
buildTool | ||
.generateBspConfig( | ||
folder, | ||
args => | ||
bspConfigGenerator.runUnconditionally(buildTool, args), | ||
statusBar, | ||
) | ||
.flatMap(_ => quickConnectToBuildServer()) | ||
case (Some(digest), _) if isBloopOrEmpty => | ||
slowConnectToBloopServer(forceImport, buildTool, digest) | ||
case (Some(digest), _) => | ||
indexer.reloadWorkspaceAndIndex( | ||
forceImport, | ||
buildTool, | ||
digest, | ||
importBuild, | ||
case Some(BuildTool.Found(buildTool: ScalaCliBuildTool, _)) | ||
if chosenBuildServer.isEmpty => | ||
tables.buildServers.chooseServer(ScalaCliBuildTool.name) | ||
val scalaCliBspConfigExists = | ||
ScalaCliBuildTool.pathsToScalaCliBsp(folder).exists(_.isFile) | ||
if (scalaCliBspConfigExists) Future.successful(BuildChange.None) | ||
else | ||
buildTool | ||
.generateBspConfig( | ||
folder, | ||
args => bspConfigGenerator.runUnconditionally(buildTool, args), | ||
statusBar, | ||
) | ||
} | ||
.flatMap(_ => quickConnectToBuildServer()) | ||
case Some(found) if isBloopOrEmpty => | ||
slowConnectToBloopServer(forceImport, found.buildTool, found.digest) | ||
case Some(found) => | ||
indexer.reloadWorkspaceAndIndex( | ||
forceImport, | ||
found.buildTool, | ||
found.digest, | ||
importBuild, | ||
) | ||
case None => | ||
Future.successful(BuildChange.None) | ||
|
||
} | ||
} yield buildChange | ||
|
||
|
@@ -2114,9 +2118,11 @@ class MetalsLspService( | |
change | ||
} | ||
|
||
private def maybeQuickConnectToBuildServer( | ||
private def onBuildTargetChanges( | ||
params: b.DidChangeBuildTarget | ||
): Unit = { | ||
// Make sure that no compilation is running, if it is it might not get completed properly | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How exactly? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure, I could not reproduce it reliably. My guess is that when you send one compile first and then change using directives in another compile requests a short while later, last one will get cancelled and the first one forgotten. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And get stuck in the queue until next cancel. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So it's a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, but it showed up here multiple times when testing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By stuck in the queue to you mean that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it seems Scala CLI doesn't always send the respond, looks like it's a race condition, but might be hard to fix. |
||
compilations.cancel() | ||
val (ammoniteChanges, otherChanges) = | ||
params.getChanges.asScala.partition { change => | ||
val connOpt = buildTargets.buildServerOf(change.getTarget) | ||
|
@@ -2145,13 +2151,19 @@ class MetalsLspService( | |
.error("Error re-importing Scala CLI build", exception) | ||
} | ||
|
||
if (otherChanges0.nonEmpty) | ||
quickConnectToBuildServer().onComplete { | ||
case Failure(e) => | ||
scribe.warn("Error refreshing build", e) | ||
case Success(_) => | ||
scribe.info("Refreshed build after change") | ||
if (otherChanges0.nonEmpty) { | ||
bspSession match { | ||
case None => scribe.warn("No build server connected") | ||
case Some(session) => | ||
for { | ||
_ <- importBuild(session) | ||
_ <- indexer.profiledIndexWorkspace(runDoctorCheck) | ||
} { | ||
focusedDocument().foreach(path => compilations.compileFile(path)) | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
def autoConnectToBuildServer(): Future[BuildChange] = { | ||
|
@@ -2238,7 +2250,6 @@ class MetalsLspService( | |
} | ||
|
||
private def importBuild(session: BspSession) = { | ||
compilers.cancel() | ||
val importedBuilds0 = timerProvider.timed("Imported build") { | ||
session.importBuilds() | ||
} | ||
|
@@ -2252,7 +2263,7 @@ class MetalsLspService( | |
} | ||
mainBuildTargetsData.resetConnections(idToConnection) | ||
} | ||
} yield () | ||
} yield compilers.cancel() | ||
} | ||
|
||
private def connectToNewBuildServer( | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a refactor to use BuildTool.Found with checksum ready.