Hi, I am trying to understand how to avoid the Inv...
# multiplatform
a
Hi, I am trying to understand how to avoid the InvalidMutabiltyException in following scenario: I have a ReconnectionManager that I want to be able to try and execute the
reconnectFun
. The idea is to trigger that function after some delay (which is incrementing from one attempt to another). The
reconnectFun
is passed from the parent class that is responsible for network error listening. I understand that my problem is that I mutate the
attempts
from with in the other thread, as well I call the
reconnectFun
but what is the proper way of doing something similar?
Copy code
internal class ReconnectionManager {
    private var attempts = 0
    private val dispatcher = CoroutineScope(Dispatchers.Main + SupervisorJob())

    fun reconnect(reconnectFun: () -> Unit) {
        dispatcher.launch {
            delay(attempts * 1000)
            withContext(Dispatchers.Default) {
                attempts++
                reconnectFun()
            }
        }
    }
}
s
This won't help you, but you can make the exception go away by calling
this.ensureNeverFrozen()
in the init block of your ReconnectionManager 😄
That's how I removed those exceptions and see earlier if something freezes up. In a similar case I changed my lambda to a flow because this won't freeze up. But in that case it was another kotlin function calling it. Flows somehow seem to have a protection against freezing stuff - maybe because there is no access to the implicit "this". I don't know if there is a way to "capture" a lambda. 🤷‍♂️
k
You can use something like this:
Copy code
​inline​ ​fun​ ​mainContinuation​( 
 ​    noinline ​block​:​ () ​->​ ​Unit 
 ​): () ​->​ ​Unit​ ​=​ ​Continuation0​( 
 ​    block, 
 ​    staticCFunction { invokerArg ​-> 
 ​        ​if​ (​NSThread​.isMainThread()) { 
 ​            invokerArg​!!​.callContinuation0() 
 ​        } ​else​ { 
 ​            dispatch_sync_f(dispatch_get_main_queue(), invokerArg, staticCFunction { args ​-> 
 ​                args​!!​.callContinuation0() 
 ​            }) 
 ​        } 
 ​    }, 
 ​    ​true 
 ​)
🙏 1
a
Thank you @Konstantin Tskhovrebov. This solution seems to work perfect on iOS. Wonder if there are any good tutorials/examples on how to properly work in multithreading environment?
@Stefan Oltmann thank you for your input as well.
s
@Anton Afanasev I also would like to see those samples ^^Because of the old memory model I struggle a lot with freezing issues. For now I have to be very careful which objects I share between Coroutines of my Main and my Default dispatcher. Let's hope the new memory model will make this easier. 🙂
🤞 1