Choi
10/22/2022, 6:14 AMCOROUTINE_SUSPENDED
Enum . If so, when exactly does COROUTINE_SUSPENDED return?reactormonk
10/22/2022, 7:24 AMFlow
isn't closable because it's cold?Brendan Weinstein
10/23/2022, 11:26 PM0 libsystem_kernel.dylib ___pthread_kill
1 libsystem_pthread.dylib _pthread_kill
2 libsystem_c.dylib _abort
3 BaseBetaiOS konan::abort() (BaseBetaiOS)
4 BaseBetaiOS (anonymous namespace)::terminateWithUnhandledException(ObjHeader*)::$_1::operator()() const (BaseBetaiOS)
5 BaseBetaiOS void (anonymous namespace)::$_0::operator()<(anonymous namespace)::terminateWithUnhandledException(ObjHeader*)::$_1>((anonymous namespace)::terminateWithUnhandledException(ObjHeader*)::$_1) (BaseBetaiOS)
6 BaseBetaiOS (anonymous namespace)::terminateWithUnhandledException(ObjHeader*) (BaseBetaiOS)
7 BaseBetaiOS (anonymous namespace)::processUnhandledException(ObjHeader*) (BaseBetaiOS)
8 BaseBetaiOS kfun:kotlinx.coroutines#handleCoroutineException(kotlin.coroutines.CoroutineContext;kotlin.Throwable){} (BaseBetaiOS)
9 BaseBetaiOS kfun:kotlinx.coroutines.StandaloneCoroutine.handleJobException#internal (BaseBetaiOS)
10 BaseBetaiOS kfun:kotlinx.coroutines.JobSupport.finalizeFinishingState#internal (BaseBetaiOS)
11 BaseBetaiOS kfun:kotlinx.coroutines.JobSupport.tryMakeCompleting#internal (BaseBetaiOS)
12 BaseBetaiOS kfun:kotlinx.coroutines.JobSupport#makeCompletingOnce(kotlin.Any?){}kotlin.Any? (BaseBetaiOS)
13 BaseBetaiOS kfun:kotlinx.coroutines.AbstractCoroutine#resumeWith(kotlin.Result<1:0>){} (BaseBetaiOS)
14 BaseBetaiOS kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} (BaseBetaiOS)
15 BaseBetaiOS kfun:kotlinx.coroutines.DispatchedTask#run(){} (BaseBetaiOS)
16 BaseBetaiOS kfun:kotlinx.coroutines.DarwinGlobalQueueDispatcher.$dispatch$lambda$0$FUNCTION_REFERENCE$693.$<bridge-UNN>invoke(){}#internal (BaseBetaiOS)
17 BaseBetaiOS ___6f72672e6a6574627261696e732e6b6f746c696e783a6b6f746c696e782d636f726f7574696e65732d636f7265_knbridge762_block_invoke (BaseBetaiOS)
18 libdispatch.dylib __dispatch_call_block_and_release
19 libdispatch.dylib __dispatch_client_callout
20 libdispatch.dylib __dispatch_root_queue_drain
21 libdispatch.dylib __dispatch_worker_thread2
22 libsystem_pthread.dylib __pthread_wqthread
Ruben Quadros
10/24/2022, 7:17 AMFlow<Int>
In this function I have an api call which also returns a flow
What is the best way to give result back to the caller?
Sample code in threadzalewski.se
10/24/2022, 5:23 PMTim Malseed
10/26/2022, 12:26 AMJoão Gabriel Zó
10/26/2022, 1:26 PMwithContext()
get it’s own coroutineScope or inherit it from whoever is calling the function?Vaibhav Nalawade
10/26/2022, 4:37 PMscope.launch{
List.forEach{
Something(it)
}
CLOVIS
10/26/2022, 7:20 PMcoroutineContext
and currentCoroutineContext()
?SecretX
10/27/2022, 11:31 AMRajar
10/31/2022, 11:09 AMsuspend
and not a non-suspend one ? If possible it could be an annotation where the ensuring would happen.
My use case is:
suspend fun <T> execute(request: suspend () -> T): T {
// code here
}
...
//code using 'execute'
execute(mySuspendLambda) // OK
execute { 1+1 } // warning or error
dawidhyzy
10/31/2022, 2:06 PMDragan Vojvodić
10/31/2022, 3:09 PMinline fun <T> Fragment.collectFlowSafely(
flowToCollect: Flow<T>,
repeatState: Lifecycle.State = Lifecycle.State.STARTED,
crossinline value: (T) -> Unit
) {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(repeatState) {
flowToCollect.collect {
value(it)
}
}
}
}
Would this way of collecting flow be safe from cancellation point of view? i.e. Would cancel the collection when the view is no longer visible etc?Sushobh
11/01/2022, 2:18 AMK Merle
11/01/2022, 7:20 AMflow
for specific amount of time, and collect all, or return null?hfhbd
11/02/2022, 9:07 AMjanvladimirmostert
11/02/2022, 10:20 AMfun blah() { ... }
suspend fun blah() { ... }
now if I'm in a coroutineContext and call blah, it calls the suspending one and if I'm not in a coroutineContext or in Java-land, it calls the non-suspending oneSam
11/02/2022, 1:21 PMlaunch
allowed to cancel itself but coroutineScope
isn’t?rocketraman
11/03/2022, 6:23 PM> Task :shared:kspKotlinFrontend FAILED
e: Could not find "org.jetbrains.kotlin:kotlinx-atomicfu-runtime" in [/home/raman/.local/share/kotlin/daemon]
e: java.lang.IllegalStateException: FATAL ERROR: Could not find "org.jetbrains.kotlin:kotlinx-atomicfu-runtime" in [/home/raman/.local/share/kotlin/daemon]
at org.jetbrains.kotlin.ir.backend.js.KlibKt$toResolverLogger$1.fatal(klib.kt:106)
This issue exists, but is marked as resolved: https://github.com/Kotlin/kotlinx.coroutines/issues/3305. I don't depend on atomicfu directly -- only indirect dependencies via coroutines.Augusto
11/05/2022, 11:02 AMdelay()
public suspend fun delay(timeMillis: Long) {
if (timeMillis <= 0) return // don't delay
return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
//some extra code
}
}
I wonder if there's a reason to do return suspendCancellableCoroutine[...]
rather than just calling suspendCancellableCoroutine()
, as delay()
returns Unit
.Alex Styl
11/07/2022, 8:29 AMerror()
doesn’t crash the app? Given there is no supervisor job I was expecting this to crash the program but it doesn’t.
I can see the ‘Starting’ the crash and then ‘job done’ in the logs 🤔
suspend fun main() {
val scope = CoroutineScope(Dispatchers.Main.immediate)
debugLn { "Starting" }
scope.launch {
error("CRASH!")
}
delay(500)
debugLn { "Job done" }
}
oday
11/07/2022, 9:07 AMvar location = mutableStateOf<GetLocation.Location?>(null)
var dateRange = mutableStateOf<DateRange?>(null)
var category = mutableStateOf(Category.All)
var period = mutableStateOf(Period.Any)
fun fetchData() {
viewModelScope.launch(<http://dispatchers.io|dispatchers.io>) {
getLocation.execute().fold(
onSuccess = { response ->
withContext(dispatchers.main) {
location.value = response.orNull()
}
},
onFailure = {
logger.log(it)
}
)
.... etc....
but I would like to observe any changes in these fields and fetch again when they’ve been updated
is there like a combineLatest?Lukas Lechner
11/07/2022, 10:17 AMWai-Wai Ng
11/07/2022, 5:02 PMgetUsdEurRate()
function is expensive, so essentially what I want is:
• Every consumer registers somewhere
• When there is an active registration, the function gets kicked off and all the consumers suspend until we get a value back
◦ As other consumers may register while the function is running
• No consumer should ever get a stale value
My first approach was to use a 0-capacity synchronization channel, but based on the above thread, it sounds like channels don't really support both "no buffered values" and "multiple consumers get the same value". Is a flow the right approach here? Or something else?Alexander
11/08/2022, 11:39 AMkotlinx-coroutines-debug
library. After sending a SIGTRAP
signal there are coroutines stacktraces like following:
Coroutine StandaloneCoroutine{Active}@4491c16c, state: SUSPENDED
...
Coroutine StandaloneCoroutine{Active}@27559007, state: SUSPENDED
...
However it is not possible to understand which stack belongs to which coroutine. All my coroutines have unique names. Is it possible to activate printing coroutine names?Joel Steres
11/11/2022, 6:01 PMobserveLoginState().map { it is LoggedIn }
.distinctUntilChanged()
.flatMapLatest { isLoggedIn ->
if (isLoggedIn) { dataSource.observe() }
else { emptyFlow() }
}
...
.flatMap {}
,,,
,launchedIn(scope)
However it really seems like the downstream flatMaps are continuing to observe even when a flatMapLatest upstream has changed. Am I doing something wrong? Is there a way to cancel the downstream observers while keeping the flow alive?
A couple of other ideas I tried:
• Threading a null or sentinel value through the flow so downstream observers could be swapped out but requires too many compromises about the type of data based along the flow.
• throwing an exception and using retryWhen to restart the flow. I ran into an exception retry loop when logged out which I should have seen even before I tried. Even though I expect it could be made workable, I didn’t really spend the time looking further as it felt kludgey.Slackbot
11/11/2022, 7:00 PMDaniele Segato
11/12/2022, 5:40 PMjava.reflect.Proxy
with awful results
This proxy job is to intercept, detect if a particular exception is throw and if so unwrap it and throw the underlying exception. This has to work with suspend functions
class UnwrapExceptionProxy<T>(private val instance: T): InvocationHandler {
@Suppress("UNCHECKED_CAST")
override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
val function = method.kotlinFunction!!
return if (function.isSuspend) {
val parameters = Array(args!!.size - 1) {args[it] }
val continuation = args.last() as Continuation<Any?>
method.invoke(instance, *parameters, Continuation<Any?>(continuation.context) { result ->
val wrappedError = result.exceptionOrNull() as? MyWrapException
if (wrappedError == null) {
continuation.resumeWith(result)
} else {
continuation.resumeWith(Result.failure(wrappedError.wrapped))
}
})
} else {
val parameters = args ?: arrayOf()
try {
method.invoke(instance, *parameters)
} catch (e: MyWrapException) {
throw e.wrapped
}
}
}
}
1. First, I'm not sure if I've handled the suspend function correctly
2. I get java.lang.reflect.UndeclaredThrowableException
every time my kotlin code throws a non RuntimeException
Is there no way to write a Proxy for kotlin? I cannot force declaring all checked exceptions and I wanted to make this as transparent as possible.Exerosis
11/14/2022, 8:27 AMval test = withTimeoutOrNull(3.seconds) {
runInterruptible {
channel.receive(ByteBuffer.allocateDirect(10))
}
}
I would have expected null to be returned. Catching the exception results in a value being returned instead of null.James Eschner
11/14/2022, 4:09 PMCoroutineStart.LAZY
. It appears, that if I don’t cancel or await a response, the runBlocking
section never properly terminates. Any ideas?
fun main() = runBlocking {
val lazyDeferredInt: Deferred<Int> = async(start = CoroutineStart.LAZY) {
5
}
}
main()
println("##### [scratch] done")
that print statement never executes 😢
fun main() = runBlocking {
val lazyDeferredInt: Deferred<Int> = async(start = CoroutineStart.LAZY) {
5
}
lazyDeferredInt.await()
}
main()
println("##### [scratch] done")
now I see "##### [scratch] done"
printed
* Not a contribution *James Eschner
11/14/2022, 4:09 PMCoroutineStart.LAZY
. It appears, that if I don’t cancel or await a response, the runBlocking
section never properly terminates. Any ideas?
fun main() = runBlocking {
val lazyDeferredInt: Deferred<Int> = async(start = CoroutineStart.LAZY) {
5
}
}
main()
println("##### [scratch] done")
that print statement never executes 😢
fun main() = runBlocking {
val lazyDeferredInt: Deferred<Int> = async(start = CoroutineStart.LAZY) {
5
}
lazyDeferredInt.await()
}
main()
println("##### [scratch] done")
now I see "##### [scratch] done"
printed
* Not a contribution *phldavies
11/14/2022, 4:13 PMLAZY
you’re explicitly telling it to not start until required. As such, unless explicitly started or awaited it will not run. The outer runBlocking
scope will only complete once all child coroutines have completed, which is why you’re not seeing the last println (it’s still waiting for the unstarted async call to complete)James Eschner
11/14/2022, 4:14 PMphldavies
11/14/2022, 4:20 PM.cancel()
the deferred if you want to avoid it running in some circumstances.isActive
will return false if the deferred is either non-started or has finished (or cancelled) - either way, cancelling it in that state should be safeJames Eschner
11/14/2022, 4:26 PMfun main() = runBlocking {
// expensive operations that don't necessarily need to run
val a: Deferred<T> = async(start = CoroutineStart.LAZY) { ... }
val b: Deferred<T> = async(start = CoroutineStart.LAZY) { ... }
val c: Deferred<T> = async(start = CoroutineStart.LAZY) { ... }
if (<some condition>) {
a.await()
b.await()
c.await()
// run some logic
}
if (<some other condition) {
a.await()
// run some other logic
}
a.cancel()
b.cancel()
c.cancel()
}
But perhaps there is a better way to design this
** Not a contributionphldavies
11/14/2022, 4:54 PM.start
at the beginning of each block so that they’re executed concurrently. Possibly using a helper such as fun startAll(varargs jobs: Job) = jobs.forEach(Job::start)
.
You can also use a helper async
wrapper such as
val deferreds = mutableListOf<Deferred<*>>()
fun <T> lazyAsync(block: suspend CoroutineScope.() -> T)
= async(start = CoroutineStart.LAZY, block = block).also(deferreds::add)
val a = lazyAsync { ... }
val b = lazyAsync { ... }
val c = lazyAsync { ... }
if (<some condition>) {
startAll(a, b, c)
// logic using a.await() etc where value needed
}
// etc
deferreds.forEach(Job::cancel)
gildor
11/15/2022, 2:48 AMa, b, c
to own function and a
to one more function, so it would be easy to read and it would run in paraleld
and get hanging code because of thisfun main() = runBlocking {
if (< some condition >) {
doABC()
// run some logic
}
if (< some other condition >) {
doA()
// run some other logic
}
}
suspend fun doABC() = coroutineScope {
// Run all operations in paralel
listOf(
async { doA() },
async { doB() },
async { doC() }
).awaitAll()
}
suspend fun doA() {}
suspend fun doB() {}
suspend fun doC() {}
fun main() = runBlocking {
val aDeferred = async { doA() }
if ( < some condition >) {
doABC(aDeferred)
// run some logic
}
if ( < some other condition) {
aDeferred.await()
// run some other logic
}
}
suspend fun doABC(aDeferred: Deferred<Foo>) = coroutineScope {
listOf(
aDeferred,
async { doB() },
async { doB() }
).awaitAll()
}
suspend fun doA() {}
suspend fun doB() {}
suspend fun doC() {}