From 666c795c93c8c897dcf5330eeac8128c037e009b Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 14 Mar 2026 15:03:45 +0000 Subject: [PATCH] fix: use correct cancellation checks in suspend functions isActive is a CoroutineScope extension and has no CoroutineScope receiver in plain suspend fun bodies (runSync, downloadFromRelay). - runSync catch block: split into CancellationException (rethrow) + Exception, removing the invalid isActive guard entirely - downloadFromRelay while loop: while(isActive) -> while(true) with coroutineContext.ensureActive() as the first statement, which works in any suspend fun and throws CancellationException when cancelled The isActive import is kept for the supervisorScope lambda in downloadFromPool, where a CoroutineScope receiver is in scope. https://claude.ai/code/session_01U8qF9mK4UBvXsXP1zNMXfX --- .../loggedIn/relays/eventsync/EventSyncViewModel.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSyncViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSyncViewModel.kt index 1469a76e9..39891277e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSyncViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/eventsync/EventSyncViewModel.kt @@ -33,6 +33,8 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.supervisorScope @@ -237,10 +239,10 @@ class EventSyncViewModel( totalEventsSent = totalSent.get().toInt(), durationMs = System.currentTimeMillis() - startTime, ) + } catch (e: CancellationException) { + throw e } catch (e: Exception) { - if (isActive) { - _syncState.value = SyncState.Error(e.message ?: "Unknown error") - } + _syncState.value = SyncState.Error(e.message ?: "Unknown error") } } @@ -287,7 +289,8 @@ class EventSyncViewModel( ) { var until: Long? = null - while (isActive) { + while (true) { + coroutineContext.ensureActive() val pageCount = AtomicInteger(0) val pageMinTs = AtomicLong(Long.MAX_VALUE) val done = Channel(Channel.CONFLATED)