David Khol
08/15/2021, 9:37 AMCoroutineScope
.
Real life example which I came across so many times can be a convenience method like this:
fun launchWithLoading(action: suspend () -> Unit) {
scope.launch {
try {
loading = true
action()
} finally {
loading = false
}
}
}
Nothing prevents the developer from calling it in a suspending context like:
suspend fun alreadySuspending() {
launchWithLoading {
// do stuff
}
}
or like
fun first() {
launchWithLoading {
another()
}
}
fun another() {
launchWithLoading {
// calculate something
}
}
although rarely they intend to break the structured concurrency.
I wonder if there is something like Android Lint but that is purely for Kotlin?
Almost everything I've found on the internet points me in the direction of Android Lint. But since this unrelated to Android, I would like to solve it without coupling the solution to Android or Android Studio, so that it can be potentially used in IntelliJ IDEA as well.Dominaezzz
08/15/2021, 9:41 AMDavid Khol
08/15/2021, 9:45 AMfun first() {
launchWithLoading {
another()
finishedEvents.value = Unit
}
}
fun another() {
launchWithLoading {
// heavy calculations
}
}
Now, finishedEvents
will be triggered even though another()
did not finish its work 😞loading
being thread unsafe. I simplified it here but could be easily solved with AtomicInteger
counting how many coroutines are currently "loading".Dominaezzz
08/15/2021, 9:49 AMlaunchWithLoading
should probably just be a suspend function there, so you're right.David Khol
08/15/2021, 9:53 AM@RequiresNonSuspendingContext
that would work similarly to how @Deprecated
or @Nullable
annotations work.
I am able to create an IDE plugin to visually highlight the incriminated piece of code as a warning/error, but that is still just highlighting.
It would be better if it could be run as a part of Gradle build so that it could be used in CI as well.Dominaezzz
08/15/2021, 10:10 AMephemient
08/15/2021, 5:20 PMTomasz Krakowiak
08/16/2021, 9:47 AM