From 7b0e0a9e965b5a9790e75b75d648d16b1bc3549c Mon Sep 17 00:00:00 2001 From: MituuZ <55958056+MituuZ@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:01:29 +0300 Subject: [PATCH] Mitigate InterruptedException | Improved task cancelling (#79) * Improve task cancelling * Increment version and add change notes * Update testing version --- build.gradle.kts | 7 +- src/main/kotlin/com/mituuz/fuzzier/Fuzzier.kt | 70 ++++++++++++------- .../kotlin/com/mituuz/fuzzier/FuzzyMover.kt | 52 ++++++++------ .../com/mituuz/fuzzier/StringEvaluator.kt | 13 +++- .../fuzzier/components/TestBenchComponent.kt | 21 +++--- .../kotlin/com/mituuz/fuzzier/TestUtil.kt | 2 +- 6 files changed, 103 insertions(+), 62 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7e7f8b1b..fcf87b11 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } // Use same version and group for the jar and the plugin -val currentVersion = "1.0.0" +val currentVersion = "1.1.0" val myGroup = "com.mituuz" version = currentVersion group = myGroup @@ -23,7 +23,7 @@ repositories { dependencies { intellijPlatform { - intellijIdeaCommunity("2024.2.0.1") + intellijIdeaCommunity("2024.2.1") pluginVerifier() zipSigner() @@ -61,8 +61,7 @@ intellijPlatform { changeNotes = """

Version $currentVersion

- - Re-implement project file handling as a backup if no modules are present
- - Migrate IntelliJ Platform Gradle Plugin to 2.x + - Improve task cancelling to avoid InterruptedException and reduce cancelling delay
""".trimIndent() ideaVersion { diff --git a/src/main/kotlin/com/mituuz/fuzzier/Fuzzier.kt b/src/main/kotlin/com/mituuz/fuzzier/Fuzzier.kt index bfd546bf..c59beea3 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/Fuzzier.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/Fuzzier.kt @@ -50,6 +50,7 @@ import com.mituuz.fuzzier.entities.FuzzyMatchContainer import com.mituuz.fuzzier.settings.FuzzierSettingsService.RecentFilesMode.NONE import org.apache.commons.lang3.StringUtils import java.awt.event.* +import java.util.concurrent.Future import javax.swing.* import kotlin.coroutines.cancellation.CancellationException @@ -151,14 +152,7 @@ open class Fuzzier : FuzzyAction() { override fun updateListContents(project: Project, searchString: String) { if (StringUtils.isBlank(searchString)) { - if (fuzzierSettingsService.state.recentFilesMode != NONE) { - createInitialView(project) - } else { - ApplicationManager.getApplication().invokeLater { - component.fileList.model = DefaultListModel() - defaultDoc?.let { (component as FuzzyFinderComponent).previewPane.updateFile(it) } - } - } + handleEmptySearchString(project) return } @@ -170,26 +164,17 @@ open class Fuzzier : FuzzyAction() { component.fileList.setPaintBusy(true) var listModel = DefaultListModel() - val stringEvaluator = StringEvaluator( - fuzzierSettingsService.state.exclusionSet, - fuzzierSettingsService.state.modules, - changeListManager - ) + val stringEvaluator = getStringEvaluator() - if (task?.isCancelled == true) throw CancellationException() + if (task?.isCancelled == true) return@executeOnPooledThread - val moduleManager = ModuleManager.getInstance(project) - if (fuzzierSettingsService.state.isProject) { - processProject(project, stringEvaluator, searchString, listModel) - } else { - processModules(moduleManager, stringEvaluator, searchString, listModel) - } + process(project, stringEvaluator, searchString, listModel, task) - if (task?.isCancelled == true) throw CancellationException() + if (task?.isCancelled == true) return@executeOnPooledThread listModel = fuzzierUtil.sortAndLimit(listModel) - if (task?.isCancelled == true) throw CancellationException() + if (task?.isCancelled == true) return@executeOnPooledThread ApplicationManager.getApplication().invokeLater { component.fileList.model = listModel @@ -199,23 +184,54 @@ open class Fuzzier : FuzzyAction() { component.fileList.setSelectedValue(listModel[0], true) } } + } catch (e: InterruptedException) { + return@executeOnPooledThread } catch (e: CancellationException) { - // Do nothing + return@executeOnPooledThread + } + } + } + + private fun handleEmptySearchString(project: Project) { + if (fuzzierSettingsService.state.recentFilesMode != NONE) { + createInitialView(project) + } else { + ApplicationManager.getApplication().invokeLater { + component.fileList.model = DefaultListModel() + defaultDoc?.let { (component as FuzzyFinderComponent).previewPane.updateFile(it) } } } } + private fun getStringEvaluator(): StringEvaluator { + return StringEvaluator( + fuzzierSettingsService.state.exclusionSet, + fuzzierSettingsService.state.modules, + changeListManager + ) + } + + private fun process(project: Project, stringEvaluator: StringEvaluator, searchString: String, + listModel: DefaultListModel, task: Future<*>?) { + val moduleManager = ModuleManager.getInstance(project) + if (fuzzierSettingsService.state.isProject) { + processProject(project, stringEvaluator, searchString, listModel, task) + } else { + processModules(moduleManager, stringEvaluator, searchString, listModel, task) + } + } + private fun processProject(project: Project, stringEvaluator: StringEvaluator, - searchString: String, listModel: DefaultListModel) { - val contentIterator = stringEvaluator.getContentIterator(project.name, searchString, listModel) + searchString: String, listModel: DefaultListModel, task: Future<*>?) { + val contentIterator = stringEvaluator.getContentIterator(project.name, searchString, listModel, task) ProjectFileIndex.getInstance(project).iterateContent(contentIterator) } private fun processModules(moduleManager: ModuleManager, stringEvaluator: StringEvaluator, - searchString: String, listModel: DefaultListModel) { + searchString: String, listModel: DefaultListModel, task: Future<*>?) { for (module in moduleManager.modules) { val moduleFileIndex = module.rootManager.fileIndex - val contentIterator = stringEvaluator.getContentIterator(module.name, searchString, listModel) + val contentIterator = stringEvaluator.getContentIterator(module.name, searchString, listModel, task) moduleFileIndex.iterateContent(contentIterator) } } diff --git a/src/main/kotlin/com/mituuz/fuzzier/FuzzyMover.kt b/src/main/kotlin/com/mituuz/fuzzier/FuzzyMover.kt index a3b7cfb8..6a6ba630 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/FuzzyMover.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/FuzzyMover.kt @@ -51,6 +51,7 @@ import com.mituuz.fuzzier.entities.FuzzyMatchContainer import org.apache.commons.lang3.StringUtils import java.awt.event.* import java.util.concurrent.CompletableFuture +import java.util.concurrent.Future import javax.swing.* import kotlin.coroutines.cancellation.CancellationException @@ -203,25 +204,17 @@ class FuzzyMover : FuzzyAction() { component.fileList.setPaintBusy(true) var listModel = DefaultListModel() - val stringEvaluator = StringEvaluator( - fuzzierSettingsService.state.exclusionSet, - fuzzierSettingsService.state.modules - ) + val stringEvaluator = getStringEvaluator() - if (task?.isCancelled == true) throw CancellationException() + if (task?.isCancelled == true) return@executeOnPooledThread - val moduleManager = ModuleManager.getInstance(project) - if (fuzzierSettingsService.state.isProject) { - processProject(project, stringEvaluator, searchString, listModel) - } else { - processModules(moduleManager, stringEvaluator, searchString, listModel) - } + process(project, stringEvaluator, searchString, listModel, task) - if (task?.isCancelled == true) throw CancellationException() + if (task?.isCancelled == true) return@executeOnPooledThread listModel = fuzzierUtil.sortAndLimit(listModel, true) - if (task?.isCancelled == true) throw CancellationException() + if (task?.isCancelled == true) return@executeOnPooledThread ApplicationManager.getApplication().invokeLater { component.fileList.model = listModel @@ -231,31 +224,50 @@ class FuzzyMover : FuzzyAction() { component.fileList.setSelectedValue(listModel[0], true) } } + } catch (e: InterruptedException) { + return@executeOnPooledThread } catch (e: CancellationException) { - // Do nothing + return@executeOnPooledThread } } } + + private fun getStringEvaluator(): StringEvaluator { + return StringEvaluator( + fuzzierSettingsService.state.exclusionSet, + fuzzierSettingsService.state.modules + ) + } + private fun process(project: Project, stringEvaluator: StringEvaluator, searchString: String, + listModel: DefaultListModel, task: Future<*>?) { + val moduleManager = ModuleManager.getInstance(project) + if (fuzzierSettingsService.state.isProject) { + processProject(project, stringEvaluator, searchString, listModel, task) + } else { + processModules(moduleManager, stringEvaluator, searchString, listModel, task) + } + } + private fun processProject(project: Project, stringEvaluator: StringEvaluator, - searchString: String, listModel: DefaultListModel) { + searchString: String, listModel: DefaultListModel, task: Future<*>?) { val contentIterator = if (!component.isDirSelector) { - stringEvaluator.getContentIterator(project.name, searchString, listModel) + stringEvaluator.getContentIterator(project.name, searchString, listModel, task) } else { - stringEvaluator.getDirIterator(project.name, searchString, listModel) + stringEvaluator.getDirIterator(project.name, searchString, listModel, task) } ProjectFileIndex.getInstance(project).iterateContent(contentIterator) } private fun processModules(moduleManager: ModuleManager, stringEvaluator: StringEvaluator, - searchString: String, listModel: DefaultListModel) { + searchString: String, listModel: DefaultListModel, task: Future<*>?) { for (module in moduleManager.modules) { val moduleFileIndex = module.rootManager.fileIndex val contentIterator = if (!component.isDirSelector) { - stringEvaluator.getContentIterator(module.name, searchString, listModel) + stringEvaluator.getContentIterator(module.name, searchString, listModel, task) } else { - stringEvaluator.getDirIterator(module.name, searchString, listModel) + stringEvaluator.getDirIterator(module.name, searchString, listModel, task) } moduleFileIndex.iterateContent(contentIterator) } diff --git a/src/main/kotlin/com/mituuz/fuzzier/StringEvaluator.kt b/src/main/kotlin/com/mituuz/fuzzier/StringEvaluator.kt index a201e4cb..38683567 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/StringEvaluator.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/StringEvaluator.kt @@ -28,6 +28,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManager import com.intellij.openapi.vfs.VirtualFile import com.mituuz.fuzzier.entities.FuzzyMatchContainer import com.mituuz.fuzzier.entities.ScoreCalculator +import java.util.concurrent.Future import javax.swing.DefaultListModel /** @@ -42,9 +43,13 @@ class StringEvaluator( ) { lateinit var scoreCalculator: ScoreCalculator - fun getContentIterator(moduleName: String, searchString: String, listModel: DefaultListModel): ContentIterator { + fun getContentIterator(moduleName: String, searchString: String, listModel: DefaultListModel, + task: Future<*>?): ContentIterator { scoreCalculator = ScoreCalculator(searchString) return ContentIterator { file: VirtualFile -> + if (task?.isCancelled == true) { + return@ContentIterator false + } if (!file.isDirectory) { val moduleBasePath = modules[moduleName] ?: return@ContentIterator true @@ -63,9 +68,13 @@ class StringEvaluator( } } - fun getDirIterator(moduleName: String, searchString: String, listModel: DefaultListModel): ContentIterator { + fun getDirIterator(moduleName: String, searchString: String, listModel: DefaultListModel, + task: Future<*>?): ContentIterator { scoreCalculator = ScoreCalculator(searchString) return ContentIterator { file: VirtualFile -> + if (task?.isCancelled == true) { + return@ContentIterator false + } if (file.isDirectory) { val moduleBasePath = modules[moduleName] ?: return@ContentIterator true val filePath = getDirPath(file, moduleBasePath, moduleName) diff --git a/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt b/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt index 7db204ca..bc8b4d26 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt @@ -145,12 +145,7 @@ class TestBenchComponent : JPanel() { table.setPaintBusy(true) val listModel = DefaultListModel() - val moduleManager = ModuleManager.getInstance(project) - if (service().state.isProject) { - processProject(project, stringEvaluator, searchString, listModel) - } else { - processModules(moduleManager, stringEvaluator, searchString, listModel) - } + process(project, stringEvaluator, searchString, listModel) val sortedList = listModel.elements().toList().sortedByDescending { it.getScore() } val data = sortedList.map { @@ -163,10 +158,20 @@ class TestBenchComponent : JPanel() { table.setPaintBusy(false) } } + + private fun process(project: Project, stringEvaluator: StringEvaluator, searchString: String, + listModel: DefaultListModel) { + val moduleManager = ModuleManager.getInstance(project) + if (service().state.isProject) { + processProject(project, stringEvaluator, searchString, listModel) + } else { + processModules(moduleManager, stringEvaluator, searchString, listModel) + } + } private fun processProject(project: Project, stringEvaluator: StringEvaluator, searchString: String, listModel: DefaultListModel) { - val contentIterator = stringEvaluator.getContentIterator(project.name, searchString, listModel) + val contentIterator = stringEvaluator.getContentIterator(project.name, searchString, listModel, null) val scoreCalculator = stringEvaluator.scoreCalculator scoreCalculator.setMultiMatch(liveSettingsComponent.multiMatchActive.getCheckBox().isSelected) @@ -181,7 +186,7 @@ class TestBenchComponent : JPanel() { searchString: String, listModel: DefaultListModel) { for (module in moduleManager.modules) { val moduleFileIndex = module.rootManager.fileIndex - val contentIterator = stringEvaluator.getContentIterator(module.name, searchString, listModel) + val contentIterator = stringEvaluator.getContentIterator(module.name, searchString, listModel, null) val scoreCalculator = stringEvaluator.scoreCalculator scoreCalculator.setMultiMatch(liveSettingsComponent.multiMatchActive.getCheckBox().isSelected) diff --git a/src/test/kotlin/com/mituuz/fuzzier/TestUtil.kt b/src/test/kotlin/com/mituuz/fuzzier/TestUtil.kt index 946fe432..d3b77626 100644 --- a/src/test/kotlin/com/mituuz/fuzzier/TestUtil.kt +++ b/src/test/kotlin/com/mituuz/fuzzier/TestUtil.kt @@ -89,7 +89,7 @@ class TestUtil { stringEvaluator = StringEvaluator(exclusionList, map) } - val contentIterator = stringEvaluator.getContentIterator(myFixture.module.name, "", filePathContainer) + val contentIterator = stringEvaluator.getContentIterator(myFixture.module.name, "", filePathContainer, null) val index = myFixture.module.rootManager.fileIndex runInEdtAndWait { index.iterateContent(contentIterator)