Is there a known issue that `ensureNeverFrozen()` ...
# kotlin-native
d
Is there a known issue that
ensureNeverFrozen()
does not generate an exception or not caught on ios?
a
Hello! Can you tell a bit more on your case?
d
asking because I'm running into unexpected frozen issues and adding
ensureNeverFrozen()
seams to cancel my coroutine execution.
Give me a minute. I'll try to create a gist of the most important bits
k
You may be running into issues internal to coroutines, assuming you are using the multithreaded branch.
ensureNeverFrozen()
will prevent objects from freezing, but if that happens while coroutines is doing something internal, coroutines may stop and you won’t get an exception. I have seen this. Sometimes you’ll get a log about “machinery”. If you see that, it’s definitely inside the coroutines. I suspect some of the internals of coroutines are not prepared for the kinds of exceptions that come from
ensureNeverFrozen()
, as previously you couldn’t get exceptions in that way unless it was something like OOM.
What are you trying to do?
d
The funny thing is this gist works as expected... but my more advanced code doesn't...
k
Copy code
init {
        //ensureNeverFrozen()
    }
I assume if you uncomment that it doesn’t work?
d
If I add
ensureNeverFrozen()
to the presenters
init
it just stops working as my output is
launched -- this.isFrozen:false
from line 21
k
Copy code
val contentFromNetwork = withContext(<http://CoroutineContextProvider.IO|CoroutineContextProvider.IO>) {
                // interactor causes this to freeze
                interactor.getContent()
            }
interactor is a field of the presenter. When you move threads, you freeze the lambda and anything in it. Capturing the field freezes the presenter.
That will fail when
ensureNeverFrozen()
is called before the lambda
d
Yes, this is what I learned today.. actually from your blogpost. Many thanks! Though my main problem was not this accidental freeze but rather the not getting the exception from
ensureNeverFrozen
. In any case I'd rather have the
FreezingException
compared to the silent failure.
Wrapping it inside a try/catch
Copy code
val contentFromNetwork: List<Content> = try {
    withContext(Dispatchers.Default) {
        // interactor causes this to freeze
        interactor.getContent()
    }
} catch (t: Throwable) {
    printThrowable(t)
    emptyList()
}
Gives me:
launched -- this.isFrozen:false
kotlin.native.concurrent.FreezingException: freezing of kotlinx.coroutines.$startCoroutine$lambda-0$FUNCTION_REFERENCE$30@15583c8 has failed, first blocker is common.presentation.content.TestPresenter@1d8948
k
first blocker is common.presentation.content.TestPresenter
It’s trying to freeze TestPresenter
d
Yeah, this was on purpose. I explicitly constructed it to freeze
TestPresenter
. I expected
ensureNeverFrozen()
to throw an exception in the original snippet when the freeze was happening. Instead of an exception being thrown ... the coroutine stopped working without any indication.
littering the code with log statements to find where
this
got accidentally frozen is a tedious task ... which I don't like to repeat or have to sell to my iOS colleagues
k
withContext
and similar methods I think need to be modified for the case where something fails. In the JVM version, I don’t think anything would normally fail. Internally, it’s just moving state between threads. In native, the internal coroutines code doesn’t expect that to fail and apparently doesn’t throw properly
littering the code with log statements to find where  this got accidentally frozen is a tedious task
Agree. Updating coroutines to throw when
ensureNeverFrozen()
fails should help that case significantly. I also built an intellij plugin to warn you about trapping state like that, but we’re not sure yet if it’s going to be released. In this case it definitely would’ve warned you.
👍 4
d
I'd like that plugin idea and would use it. I think it helps at lot getting familiar with coroutines and kmp. At least with the current state of MT-coroutines on native. I'll create an issue to throw/catch these exceptions. Thanks again for the help and extensive articles on the subject.
p
@kpgalligan I would certainly be interested in such a plugin - even if there were caveats around it’s accuracy