Getting weird behaviour with `produceState` and `a...
# compose
a
Getting weird behaviour with
produceState
and
awaitDispose
with the code snippets in thread
Copy code
// this fun is just of logging composable getting added or removed from composition
@Composable
private inline fun LogAttachOrDetach(crossinline tag: () -> String) {
    LaunchedEffect(Unit) {
        Log.d("ProduceEffect", "${tag()}: Added in composition")
        try
        {
            while (true)
            {
                delay(1000)
            }
        }
        catch (e: CancellationException)
        {
            Log.d("ProduceEffect", "${tag()}: Removed from composition")
            throw e
        }
    }
}

@Composable
private fun ProduceEffectParent() {
    var shouldAnimate by remember {
        mutableStateOf(true)
    }
    ProduceEffectChild(shouldAnimate) { shouldAnimate = it }
}

@Composable
private fun ProduceEffectChild(shouldAnimate: Boolean, onStateChange: (Boolean) -> Unit) {
    if (shouldAnimate) {
        LogAttachOrDetach { "ProduceEffectChild when true" }
        produceState(0) {
            value = 1
            // animation handled
            Log.d("ProduceEffect", "inside produce state before setting value to false")
            onStateChange(false)
            Log.d("ProduceEffect", "inside produce state after setting value to false and before delay")
            // this will now avoid the call to awaitDispose
            delay(100)
            Log.d("ProduceEffect", "inside produce state after setting value to false and after delay if possible")
            awaitDispose { Log.d("ProduceEffect", "disposed called for produce state") }
        }
    } else {
        LogAttachOrDetach{ "ProduceEffectChild when false" }
    }
}
now when
delay(100)
is present
awaitDispos
doesn't get called most of time with the following logs
Copy code
ProduceEffectChild when true: Added in composition
inside produce state before setting value to false
inside produce state after setting value to false and before delay
ProduceEffectChild when true: Removed from composition
ProduceEffectChild when false: Added in composition
but when
delay(100)
is comment then
awaitDispose
gets called correctly like below
Copy code
ProduceEffectChild when true: Added in composition                                       
inside produce state before setting value to false                                       
inside produce state after setting value to false and before delay                       
inside produce state after setting value to false and after delay if possible            
disposed called for produce state                                                        
ProduceEffectChild when true: Removed from composition                                   
ProduceEffectChild when false: Added in composition
I think in case when I explicitly call
onStateChange
with
false
to remove the produce state from composition, then it's scope gets cancelled any
delay(100)
gets stuck. But even in that case should
awaitDispose
gets called? Also with
delay(100)
this behaviour where
awaitDispose
doesn't get called is not consistent