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)