mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
PY-88070 Fix SlowOperations on EDT in PyProjectModelStartupActivity
Move FilenameIndex check off the EDT by using MutableSharedFlow to relay DumbService.exitDumbMode events to a coroutine that performs the index lookup via smartReadAction. (cherry picked from commit 834b84efaec3f28892f73321d4ee226ccd59a008) (cherry picked from commit f38b22c1d6f658c4b984a5c9a8e48d87ae3a1774) IJ-MR-194704 GitOrigin-RevId: 8737c9f5273c66140bf39e3ae75d68b9bc325848
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4cdfb36676
commit
a524aa71ee
@@ -5,7 +5,8 @@ import com.intellij.notification.Notification
|
||||
import com.intellij.notification.NotificationAction
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.notification.impl.NotificationFullContent
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.smartReadAction
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
@@ -16,6 +17,9 @@ import com.intellij.python.pyproject.model.PyProjectModelSettings
|
||||
import com.intellij.python.pyproject.model.PyProjectModelSettings.FeatureState.ASK
|
||||
import com.intellij.python.pyproject.model.PyProjectModelSettings.FeatureState.OFF
|
||||
import com.intellij.python.pyproject.model.PyProjectModelSettings.FeatureState.ON
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.Nls
|
||||
|
||||
private const val NOTIFICATION_GROUP_ID = "PyProject.toml"
|
||||
@@ -31,11 +35,7 @@ internal suspend fun askUserIfPyProjectMustBeEnabled(project: Project) {
|
||||
val settings = PyProjectModelSettings.getInstance(project)
|
||||
if (!settings.showConfigurationNotification) return
|
||||
|
||||
val hasPyprojectToml = readAction {
|
||||
!project.isDisposed && FilenameIndex.getVirtualFilesByName(PY_PROJECT_TOML, GlobalSearchScope.projectScope(project)).isNotEmpty()
|
||||
}
|
||||
|
||||
if (hasPyprojectToml) {
|
||||
if (hasPyprojectToml(project)) {
|
||||
showNotification(project, settings)
|
||||
}
|
||||
else {
|
||||
@@ -43,32 +43,50 @@ internal suspend fun askUserIfPyProjectMustBeEnabled(project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for `pyproject.toml` appearing in the project after startup.
|
||||
*
|
||||
* Subscribes to [DumbService.DUMB_MODE] and checks the filename index each time the IDE
|
||||
* exits dumb mode (i.e., indexing completes).
|
||||
*
|
||||
* Uses [MutableSharedFlow] with `replay = 1` so that an event emitted before
|
||||
* [collect][kotlinx.coroutines.flow.collect] starts is not lost.
|
||||
* [DROP_LATEST][BufferOverflow.DROP_LATEST] silently drops overflow since all events
|
||||
* are identical `Unit` signals.
|
||||
*/
|
||||
private fun listenForPyprojectToml(project: Project, settings: PyProjectModelSettings) {
|
||||
val disposable = Disposer.newDisposable("PyProjectModelStartupActivity")
|
||||
Disposer.register(settings, disposable)
|
||||
|
||||
val dumbModeExited = MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_LATEST)
|
||||
|
||||
project.messageBus.connect(disposable).subscribe(DumbService.DUMB_MODE, object : DumbService.DumbModeListener {
|
||||
override fun exitDumbMode() {
|
||||
dumbModeExited.tryEmit(Unit)
|
||||
}
|
||||
})
|
||||
|
||||
project.service<PyProjectScopeService>().scope.launch {
|
||||
dumbModeExited.collect {
|
||||
if (!settings.showConfigurationNotification) {
|
||||
Disposer.dispose(disposable)
|
||||
return
|
||||
return@collect
|
||||
}
|
||||
|
||||
val hasAnyPyprojectToml = FilenameIndex.hasVirtualFileWithName(
|
||||
PY_PROJECT_TOML,
|
||||
true,
|
||||
GlobalSearchScope.projectScope(project),
|
||||
null
|
||||
)
|
||||
|
||||
if (hasAnyPyprojectToml) {
|
||||
if (hasPyprojectToml(project)) {
|
||||
Disposer.dispose(disposable)
|
||||
showNotification(project, settings)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun hasPyprojectToml(project: Project): Boolean =
|
||||
smartReadAction(project) {
|
||||
!project.isDisposed &&
|
||||
FilenameIndex.hasVirtualFileWithName(PY_PROJECT_TOML, true, GlobalSearchScope.projectScope(project), null)
|
||||
}
|
||||
|
||||
private fun showNotification(project: Project, settings: PyProjectModelSettings) {
|
||||
FullContentNotification(
|
||||
NOTIFICATION_GROUP_ID,
|
||||
|
||||
Reference in New Issue
Block a user