mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 23:21:59 +01:00
Re-notify replay on every connectivity change, not just availability flips
conflate rather than distinctUntilChanged: switching between two available networks (WiFi LAN server -> cellular -> WiFi) kept the signal true, so the queue never drained until another trigger. Emit on each callback instead, and drop the sink combine's distinctUntilChanged so a repeated ready edge still flushes. Simplify flush to reuse the safe drain. Add a regression test that replays on two true emissions with no false between.
This commit is contained in:
@@ -17,6 +17,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@@ -170,6 +171,44 @@ class PendingServerActionSinkTest {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun aNetworkSwitchThatStaysAvailableReplaysAgain() =
|
||||
runBlocking {
|
||||
offline.value = false
|
||||
val network = MutableSharedFlow<Boolean>(replay = 1, extraBufferCapacity = 1)
|
||||
network.tryEmit(false)
|
||||
val reconnectScope = CoroutineScope(SupervisorJob() + UnconfinedTestDispatcher())
|
||||
try {
|
||||
val reconnectable =
|
||||
PendingServerActionSink(
|
||||
delegate = delegate,
|
||||
db = db,
|
||||
activeSourceId = { sourceId },
|
||||
offline = offline,
|
||||
offlinePreferences = flowOf(false),
|
||||
networkAvailable = network,
|
||||
scope = reconnectScope,
|
||||
)
|
||||
delegate.scrobbleFailure = IOException("down")
|
||||
reconnectable.scrobble("s1", 1_000)
|
||||
delegate.scrobbleFailure = null
|
||||
network.tryEmit(true)
|
||||
awaitUntil("the first replay") { delegate.calls.size == 1 }
|
||||
|
||||
delegate.scrobbleFailure = IOException("down")
|
||||
reconnectable.scrobble("s2", 2_000)
|
||||
delegate.scrobbleFailure = null
|
||||
// No false in between: an available-network switch must still re-notify.
|
||||
network.tryEmit(true)
|
||||
|
||||
awaitUntil("the second replay") { delegate.calls.size == 2 }
|
||||
assertEquals(listOf(Call.Scrobble("s1", 1_000), Call.Scrobble("s2", 2_000)), delegate.calls)
|
||||
} finally {
|
||||
cancelAndJoinBlocking(reconnectScope)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anOfflineUnstarCoalescesAwayAnEarlierStar() =
|
||||
runBlocking {
|
||||
|
||||
Reference in New Issue
Block a user