From a06ba79aeef668020fd441b739cf91a2d15e9240 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 13 Mar 2023 16:21:28 +0100 Subject: [PATCH] vcs: work around 'coroutineToIndicator' cancellation GitOrigin-RevId: 91a873513decc6fec836654310e3e3f3b6b44e7a --- .../openapi/vcs/changes/ui/AsyncChangesTree.kt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AsyncChangesTree.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AsyncChangesTree.kt index b1c3dba0d384..ea8f41029070 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AsyncChangesTree.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AsyncChangesTree.kt @@ -124,7 +124,7 @@ abstract class AsyncChangesTree : ChangesTree { private fun start() { scope.launch { - _requests.collectLatest { request -> + _requests.asyncCollectLatest(scope) { request -> handleRequest(request) } } @@ -287,3 +287,19 @@ abstract class TwoStepAsyncChangesTreeModel(val scope: CoroutineScope) : Asyn return newJob.await() } } + +/** + * [coroutineToIndicator]-friendly [collectLatest] implementation. Otherwise, indicator will never be cancelled. + */ +private suspend fun Flow.asyncCollectLatest(scope: CoroutineScope, action: suspend (value: T) -> Unit) { + var lastJob: Job? = null + collect { request -> + lastJob?.let { + it.cancel() + it.join() + } + lastJob = scope.launch { + action(request) + } + } +}