ScriptDependenciesUpdater: use Job explicitly instead of futures

Cancel jobs without interrupting
This commit is contained in:
Pavel V. Talanov
2017-07-14 19:46:26 +03:00
parent 999c3c5e76
commit 42629d6f8d
@@ -28,11 +28,11 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.newvfs.BulkFileListener import com.intellij.openapi.vfs.newvfs.BulkFileListener
import com.intellij.openapi.vfs.newvfs.events.VFileEvent import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.asCoroutineDispatcher import kotlinx.coroutines.experimental.asCoroutineDispatcher
import kotlinx.coroutines.experimental.future.future import kotlinx.coroutines.experimental.launch
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.script.* import org.jetbrains.kotlin.script.*
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.script.dependencies.ScriptDependencies import kotlin.script.dependencies.ScriptDependencies
@@ -51,7 +51,7 @@ internal class ScriptDependenciesUpdater(
listenToVfsChanges() listenToVfsChanges()
} }
private class TimeStampedRequest(val future: CompletableFuture<*>, val timeStamp: TimeStamp) private class TimeStampedRequest(val job: Job, val timeStamp: TimeStamp)
private class ModStampedRequest( private class ModStampedRequest(
val modificationStamp: Long, val modificationStamp: Long,
@@ -108,13 +108,13 @@ internal class ScriptDependenciesUpdater(
return return
} }
lastRequest?.request?.future?.cancel(true) lastRequest?.request?.job?.cancel()
val (currentTimeStamp, newFuture) = sendRequest(file, scriptDefinition) val (currentTimeStamp, newJob) = sendRequest(file, scriptDefinition)
requests[path] = ModStampedRequest( requests[path] = ModStampedRequest(
file.modificationStamp, file.modificationStamp,
TimeStampedRequest(newFuture, currentTimeStamp) TimeStampedRequest(newJob, currentTimeStamp)
) )
return return
} }
@@ -133,17 +133,16 @@ internal class ScriptDependenciesUpdater(
private fun sendRequest( private fun sendRequest(
file: VirtualFile, file: VirtualFile,
scriptDef: KotlinScriptDefinition scriptDef: KotlinScriptDefinition
): Pair<TimeStamp, CompletableFuture<*>> { ): Pair<TimeStamp, Job> {
val currentTimeStamp = TimeStamps.next() val currentTimeStamp = TimeStamps.next()
val dependenciesResolver = scriptDef.dependencyResolver as AsyncDependenciesResolver val dependenciesResolver = scriptDef.dependencyResolver as AsyncDependenciesResolver
val path = file.path val path = file.path
val newFuture = future(scriptDependencyUpdatesDispatcher) { val newJob = launch(scriptDependencyUpdatesDispatcher) {
dependenciesResolver.resolveAsync( val result = dependenciesResolver.resolveAsync(
contentLoader.getScriptContents(scriptDef, file), contentLoader.getScriptContents(scriptDef, file),
(scriptDef as? KotlinScriptDefinitionFromAnnotatedTemplate)?.environment.orEmpty() (scriptDef as? KotlinScriptDefinitionFromAnnotatedTemplate)?.environment.orEmpty()
) )
}.thenAccept { result ->
val lastTimeStamp = requests[path]?.request?.timeStamp val lastTimeStamp = requests[path]?.request?.timeStamp
val isLastSentRequest = lastTimeStamp == null || lastTimeStamp == currentTimeStamp val isLastSentRequest = lastTimeStamp == null || lastTimeStamp == currentTimeStamp
if (isLastSentRequest) { if (isLastSentRequest) {
@@ -153,7 +152,7 @@ internal class ScriptDependenciesUpdater(
} }
} }
} }
return Pair(currentTimeStamp, newFuture) return Pair(currentTimeStamp, newJob)
} }
fun updateSync(file: VirtualFile, scriptDef: KotlinScriptDefinition): Boolean { fun updateSync(file: VirtualFile, scriptDef: KotlinScriptDefinition): Boolean {