Trevor Stone
01/07/2022, 7:09 PM.stateIn(
CoroutineScope(Dispatchers.Default),
SharingStarted.WhileSubscribed(),
null
)
and getting Cannot start an undispatched coroutine in another thread DefaultDispatcher from current MainThread
as an error from runTestPaul Woitaschek
01/11/2022, 11:18 AMPaul Woitaschek
01/11/2022, 11:18 AMTrevor Stone
01/11/2022, 3:43 PMTrevor Stone
01/11/2022, 5:10 PMTrevor Stone
01/11/2022, 5:10 PMTrevor Stone
01/11/2022, 5:15 PMshareIn
it is using SharingStarted.WhileSubscribed()
Trevor Stone
01/11/2022, 5:15 PMPaul Woitaschek
01/11/2022, 5:16 PMTrevor Stone
01/11/2022, 5:57 PMTrevor Stone
01/11/2022, 6:29 PMTrevor Stone
01/11/2022, 6:30 PMrunBlocking {
withContext(Dispatchers.Default) {
parentFlow().stateIn(GlobalScope, SharingStarted.WhileSubscribed(), null)
}
}
Trevor Stone
01/11/2022, 6:30 PMTrevor Stone
01/11/2022, 6:32 PMTrevor Stone
01/11/2022, 6:32 PMprivate class StartedWhileSubscribed(
private val stopTimeout: Long = 0,
private val replayExpiration: Long = Long.MAX_VALUE
) : SharingStarted {
init {
require(stopTimeout >= 0) { "stopTimeout($stopTimeout ms) cannot be negative" }
require(replayExpiration >= 0) {
"replayExpiration($replayExpiration ms) cannot be negative"
}
}
override fun command(subscriptionCount: StateFlow<Int>): Flow<SharingCommand> = subscriptionCount
.transformLatest { count ->
if (count > 0) {
emit(SharingCommand.START)
} else {
delay(stopTimeout)
if (replayExpiration > 0) {
emit(SharingCommand.STOP)
delay(replayExpiration)
}
emit(SharingCommand.STOP_AND_RESET_REPLAY_CACHE)
}
}
.dropWhile { it != SharingCommand.START } // don't emit any STOP/RESET_BUFFER to start with, only START
.distinctUntilChanged() // just in case somebody forgets it, don't leak our multiple sending of START
@OptIn(ExperimentalStdlibApi::class)
override fun toString(): String {
val params =
buildList(2) {
if (stopTimeout > 0) add("stopTimeout=${stopTimeout}ms")
if (replayExpiration < Long.MAX_VALUE) add("replayExpiration=${replayExpiration}ms")
}
return "SharingStarted.WhileSubscribed(${params.joinToString()})"
}
// equals & hashcode to facilitate testing, not documented in public contract
override fun equals(other: Any?): Boolean =
(other == SharingStarted.Eagerly) ||
(other is StartedWhileSubscribed &&
stopTimeout == other.stopTimeout &&
replayExpiration == other.replayExpiration)
override fun hashCode(): Int = stopTimeout.hashCode() * 31 + replayExpiration.hashCode()
}
Trevor Stone
01/11/2022, 6:32 PMCoroutineStart.DEFAULT
it used toTrevor Stone
01/11/2022, 6:32 PM