[maven] IDEA-346343 - fix maven progress indicator

GitOrigin-RevId: b2ed254526270bb3146b7891ff8bfea1b803974f
This commit is contained in:
Alexander Bubenchikov
2024-02-21 16:58:53 +01:00
committed by intellij-monorepo-bot
parent 3c9e6bdda5
commit d0852ed01d
9 changed files with 75 additions and 100 deletions

View File

@@ -30,6 +30,7 @@ public class MavenIndexUpdateState implements Serializable {
public enum State { public enum State {
INDEXING, INDEXING,
SUCCEED, SUCCEED,
CANCELLED,
FAILED FAILED
} }
} }

View File

@@ -83,7 +83,7 @@ public class WagonTransferListenerAdapter implements TransferListener {
@Override @Override
public void debug(String s) { public void debug(String s) {
checkCanceled();
} }
private void updateProgress(String resourceName, DownloadData data) { private void updateProgress(String resourceName, DownloadData data) {
@@ -100,7 +100,10 @@ public class WagonTransferListenerAdapter implements TransferListener {
sizeInfo = StringUtilRt.formatFileSize(data.downloaded); sizeInfo = StringUtilRt.formatFileSize(data.downloaded);
} }
else { else {
sizeInfo = ((int)100f * data.downloaded / data.total) + "% of " + StringUtilRt.formatFileSize(data.total); float fraction = (float)data.downloaded / (float)data.total;
String percentHumanReadable = String.format("%.2f", fraction * 100.0);
sizeInfo =
StringUtilRt.formatFileSize(data.downloaded) + " - " + percentHumanReadable + "% of " + StringUtilRt.formatFileSize(data.total);
} }
try { try {

View File

@@ -35,8 +35,8 @@ class MavenLuceneClassIndexServer(private val myRepo: MavenRepositoryInfo,
return myNexusIndexer.search(myIndexId, pattern, maxResult) return myNexusIndexer.search(myIndexId, pattern, maxResult)
} }
override suspend fun update(indicator: MavenProgressIndicator, explicit: Boolean) { override fun updateOrRepair(fullUpdate: Boolean, progress: MavenProgressIndicator, explicit: Boolean) {
myNexusIndexer.updateIndex(myIndexId, indicator, explicit) myNexusIndexer.updateIndex(myIndexId, progress, explicit)
myUpdateTimestamp = System.currentTimeMillis() myUpdateTimestamp = System.currentTimeMillis()
} }

View File

@@ -87,7 +87,9 @@ public class MavenRepositoriesConfigurable implements SearchableConfigurable, Co
private void doUpdateIndex() { private void doUpdateIndex() {
MavenRepositoryInfo repositoryInfo = getSelectedIndices().stream().findFirst().orElse(null); MavenRepositoryInfo repositoryInfo = getSelectedIndices().stream().findFirst().orElse(null);
MavenSystemIndicesManager.getInstance().updateIndexContentFromEDT(repositoryInfo); if (repositoryInfo != null) {
MavenSystemIndicesManager.getInstance().updateIndexContent(repositoryInfo, myProject);
}
} }
private List<MavenRepositoryInfo> getSelectedIndices() { private List<MavenRepositoryInfo> getSelectedIndices() {

View File

@@ -1,15 +1,19 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.maven.indices package org.jetbrains.idea.maven.indices
import com.intellij.ide.AppLifecycleListener
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.components.* import com.intellij.openapi.components.*
import com.intellij.openapi.progress.* import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.blockingContext
import com.intellij.openapi.progress.blockingContextToIndicator
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectCloseListener import com.intellij.openapi.project.ProjectCloseListener
import com.intellij.openapi.project.getOpenedProjects import com.intellij.openapi.project.getOpenedProjects
import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.util.registry.Registry
import com.intellij.platform.ide.progress.TaskCancellation
import com.intellij.platform.ide.progress.withBackgroundProgress
import com.intellij.util.PathUtilRt import com.intellij.util.PathUtilRt
import com.intellij.util.messages.Topic import com.intellij.util.messages.Topic
import com.intellij.util.xmlb.annotations.OptionTag import com.intellij.util.xmlb.annotations.OptionTag
@@ -59,28 +63,6 @@ class MavenSystemIndicesManager(val cs: CoroutineScope) : PersistentStateCompone
init { init {
cs.launch {
while (isActive) {
delay(2000)
val statusToSend = ArrayList<MavenIndexUpdateState>()
if (!needPoll) continue
var anyInProgress = false
status().forEach { s ->
anyInProgress = anyInProgress || s.myState == MavenIndexUpdateState.State.INDEXING
val oldStatus = luceneUpdateStatusMap[s.myUrl]
if (oldStatus == null || oldStatus.timestamp < s.timestamp) {
statusToSend.add(s)
luceneUpdateStatusMap[s.myUrl] = s
}
}
statusToSend.forEach {
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).indexStatusChanged(it)
}
needPoll = anyInProgress
}
}
ApplicationManager.getApplication().messageBus.connect().subscribe(ProjectCloseListener.TOPIC, object : ProjectCloseListener { ApplicationManager.getApplication().messageBus.connect().subscribe(ProjectCloseListener.TOPIC, object : ProjectCloseListener {
override fun projectClosed(project: Project) { override fun projectClosed(project: Project) {
@@ -127,61 +109,6 @@ class MavenSystemIndicesManager(val cs: CoroutineScope) : PersistentStateCompone
return ourTestIndicesDir ?: MavenUtil.getPluginSystemDir("Indices") return ourTestIndicesDir ?: MavenUtil.getPluginSystemDir("Indices")
} }
fun getIndexForRepoSync(repo: MavenRepositoryInfo): MavenSearchIndex {
return runBlockingMaybeCancellable {
getIndexForRepo(repo)
}
}
fun updateIndexContentSync(repo: MavenRepositoryInfo,
fullUpdate: Boolean,
explicit: Boolean,
indicator: MavenProgressIndicator) {
return runBlockingMaybeCancellable {
updateLuceneIndexContent(repo, fullUpdate, explicit, indicator)
}
}
private suspend fun updateLuceneIndexContent(repo: MavenRepositoryInfo,
fullUpdate: Boolean,
explicit: Boolean,
indicator: MavenProgressIndicator) {
coroutineScope {
val updateScope = this
val connection = ApplicationManager.getApplication().messageBus.connect(updateScope)
connection.subscribe(AppLifecycleListener.TOPIC, object : AppLifecycleListener {
override fun appClosing() {
updateScope.cancel()
indicator.cancel()
MavenLog.LOG.info("Application is closing, gracefully shutdown all indexing operations")
}
})
startUpdateLuceneIndex(repo)
}
}
fun startUpdateLuceneIndex(repo: MavenRepositoryInfo) {
val indexFile = getDirForMavenIndex(repo).toFile()
val status = getIndexWrapper().startIndexing(repo, indexFile)
needPoll = true
if (status != null) {
luceneUpdateStatusMap[repo.url] = status
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).indexStatusChanged(status)
}
}
fun stopIndexing(repo: MavenRepositoryInfo) {
getIndexWrapper().stopIndexing(repo)
}
fun status(): List<MavenIndexUpdateState> = getIndexWrapper().status()
private suspend fun getIndexForRepo(repo: MavenRepositoryInfo): MavenSearchIndex { private suspend fun getIndexForRepo(repo: MavenRepositoryInfo): MavenSearchIndex {
return cs.async(Dispatchers.IO) { return cs.async(Dispatchers.IO) {
val dir = getDirForMavenIndex(repo) val dir = getDirForMavenIndex(repo)
@@ -380,18 +307,49 @@ class MavenSystemIndicesManager(val cs: CoroutineScope) : PersistentStateCompone
return inMemoryIndices.values.toImmutableList() return inMemoryIndices.values.toImmutableList()
} }
fun updateIndexContentFromEDT(repositoryInfo: MavenRepositoryInfo) { fun updateIndexContent(repositoryInfo: MavenRepositoryInfo, project: Project) {
val task = object : Task.Backgroundable(null, IndicesBundle.message("maven.indices.updating"), true) { cs.launch(Dispatchers.IO) {
override fun run(indicator: ProgressIndicator) { withBackgroundProgress(project, IndicesBundle.message("maven.indices.updating.for.repo", repositoryInfo.url), TaskCancellation.cancellable()) {
val mavenIndicator = MavenProgressIndicator(null, indicator, null)
runBlockingCancellable {
val mavenIndex = getClassIndexForRepository(repositoryInfo) val mavenIndex = getClassIndexForRepository(repositoryInfo)
(mavenIndex as? MavenUpdatableIndex)?.update(mavenIndicator, true) blockingContext {
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).indexStatusChanged(
MavenIndexUpdateState(repositoryInfo.url,
null,
IndicesBundle.message("maven.indices.updating.for.repo", repositoryInfo.url),
MavenIndexUpdateState.State.INDEXING))
blockingContextToIndicator {
val indicator = MavenProgressIndicator(null, ProgressManager.getInstance().progressIndicator, null)
try {
(mavenIndex as? MavenUpdatableIndex)?.updateOrRepair(true, indicator, true)
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).indexStatusChanged(
MavenIndexUpdateState(repositoryInfo.url,
null,
IndicesBundle.message("maven.indices.updated.for.repo", repositoryInfo.url),
MavenIndexUpdateState.State.SUCCEED))
} }
catch (e: MavenProcessCanceledException) {
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).indexStatusChanged(
MavenIndexUpdateState(repositoryInfo.url,
e.message,
IndicesBundle.message("maven.indices.updated.for.repo", repositoryInfo.url),
MavenIndexUpdateState.State.CANCELLED))
} }
catch (e: Exception) {
if (e !is ProcessCanceledException) {
MavenLog.LOG.warn(e)
}
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).indexStatusChanged(
MavenIndexUpdateState(repositoryInfo.url,
e.message,
IndicesBundle.message("maven.index.updated.error"),
MavenIndexUpdateState.State.FAILED))
} }
ProgressManager.getInstance().run(task) }
}
}
}
} }

View File

@@ -1,13 +1,17 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.maven.indices package org.jetbrains.idea.maven.indices
import org.apache.http.annotation.Obsolete
import org.jetbrains.idea.maven.server.AddArtifactResponse import org.jetbrains.idea.maven.server.AddArtifactResponse
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException import org.jetbrains.idea.maven.utils.MavenProcessCanceledException
import org.jetbrains.idea.maven.utils.MavenProgressIndicator import org.jetbrains.idea.maven.utils.MavenProgressIndicator
import java.io.File import java.io.File
interface MavenUpdatableIndex : MavenRepositoryIndex { interface MavenUpdatableIndex : MavenRepositoryIndex {
@Deprecated("do not use it") /***
* still required in maven lucene indexer, until dropping MavenProgressIndicator
*/
@Obsolete
@Throws(MavenProcessCanceledException::class) @Throws(MavenProcessCanceledException::class)
fun updateOrRepair(fullUpdate: Boolean, progress: MavenProgressIndicator, explicit: Boolean) { fun updateOrRepair(fullUpdate: Boolean, progress: MavenProgressIndicator, explicit: Boolean) {
} }

View File

@@ -3,14 +3,16 @@ package org.jetbrains.idea.maven.navigator.actions
import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.blockingContext
import com.intellij.openapi.progress.blockingContextToIndicator
import com.intellij.openapi.project.DumbAwareAction import com.intellij.openapi.project.DumbAwareAction
import com.intellij.platform.ide.progress.TaskCancellation
import com.intellij.platform.ide.progress.withBackgroundProgress import com.intellij.platform.ide.progress.withBackgroundProgress
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jetbrains.idea.maven.indices.MavenSystemIndicesManager import org.jetbrains.idea.maven.indices.MavenSystemIndicesManager
import org.jetbrains.idea.maven.indices.MavenUpdatableIndex import org.jetbrains.idea.maven.utils.MavenCoroutineScopeProvider
import org.jetbrains.idea.maven.utils.MavenDataKeys import org.jetbrains.idea.maven.utils.MavenDataKeys
import org.jetbrains.idea.maven.utils.MavenProgressIndicator import org.jetbrains.idea.maven.utils.MavenProgressIndicator
@@ -19,9 +21,10 @@ class IndexUpdateAction : DumbAwareAction() {
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val mavenRepo = e.getData(MavenDataKeys.MAVEN_REPOSITORY) ?: return val mavenRepo = e.getData(MavenDataKeys.MAVEN_REPOSITORY) ?: return
val project = e.project ?: return
val manager = MavenSystemIndicesManager.getInstance() val manager = MavenSystemIndicesManager.getInstance()
manager.updateIndexContentFromEDT(mavenRepo) manager.updateIndexContent(mavenRepo, project)
} }
override fun getActionUpdateThread(): ActionUpdateThread { override fun getActionUpdateThread(): ActionUpdateThread {

View File

@@ -107,6 +107,7 @@ abstract class MavenIndexerWrapper : MavenRemoteObjectWrapper<MavenServerIndexer
indicator: MavenProgressIndicator, indicator: MavenProgressIndicator,
multithreaded: Boolean) { multithreaded: Boolean) {
performCancelable<Any, Exception>( performCancelable<Any, Exception>(
indicator,
RetriableCancelable<Any, Exception> { RetriableCancelable<Any, Exception> {
val indicatorWrapper = wrapAndExport(indicator) val indicatorWrapper = wrapAndExport(indicator)
try { try {

View File

@@ -18,6 +18,7 @@ package org.jetbrains.idea.maven.server
import org.jetbrains.idea.maven.execution.SyncBundle import org.jetbrains.idea.maven.execution.SyncBundle
import org.jetbrains.idea.maven.utils.MavenLog import org.jetbrains.idea.maven.utils.MavenLog
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException import org.jetbrains.idea.maven.utils.MavenProcessCanceledException
import org.jetbrains.idea.maven.utils.MavenProgressIndicator
import java.rmi.RemoteException import java.rmi.RemoteException
abstract class RemoteObjectWrapper<T> protected constructor() { abstract class RemoteObjectWrapper<T> protected constructor() {
@@ -67,12 +68,14 @@ abstract class RemoteObjectWrapper<T> protected constructor() {
} }
@Throws(MavenProcessCanceledException::class) @Throws(MavenProcessCanceledException::class)
protected fun <R, E : Exception?> performCancelable(r: RetriableCancelable<R, E>): R { protected fun <R, E : Exception?> performCancelable(indicator: MavenProgressIndicator, r: RetriableCancelable<R, E>): R {
var last: RemoteException? = null var last: RemoteException? = null
for (i in 0..1) { for (i in 0..1) {
try { try {
if (!indicator.isCanceled) {
return r.execute() return r.execute()
} }
}
catch (e: RemoteException) { catch (e: RemoteException) {
handleRemoteError(e.also { last = it }) handleRemoteError(e.also { last = it })
} }