Hello :wave: Struggling to understand this simple ...
# coroutines
m
Hello 👋 Struggling to understand this simple scenario - why does the app never finish? Both strings are printed fine, but
main
never returns 😕 All I need is for
printSomethingWithDelay
to execute on a background thread, with no new coroutine, how can I achieve that?
Copy code
fun main() {

    runBlocking {
        printSomethingWithDelay("something")
    }
    print("finished")
}

suspend fun printSomethingWithDelay(something: String) = withContext(AppDispatcher.appDispatcher){
    delay(1000)
    println(something)
}


object AppDispatcher {

    val appDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
}
s
This is not Coroutine related. Main ends fine, but your process doesn't complete, since you started a non-daemon thread by starting a new ExecutorService. Either make your ExecutorService's threads daemon-threads or shutdown your ExecutorService explicitly before main ends
☝️ 1
☝🏼 1
🙏 1
z
That’s why your process isn’t ending, but what are you actually trying to do? I assume this is a simplified version of it since this code could just be
Copy code
Thread.sleep(1000)
println(“something”)
println(“finished”)
👍 1
m
So my app uses a JavaScript context to load JS code, evaluate scripts, retrieve values, etc. I’m using LiquidCore for this and I want to make sure that all invocations on the JS environment are executed on a background thread. I don’t want to spin off new coroutines because I want to make sure all this communication with JS happens synchronously, but in the background. Perhaps using the coroutines lib here isn’t appropriate if all I want to do is start some code on a background thread… I apologise for my ignorance here 🙇🏻‍♀️
z
Probably depends on what the rest of the communication looks like. Coroutines are really good for doing asynchronous things, but they give you some nice primitives for doing things synchronously across multiple threads too.
m
are you referring to
Mutex
, for example? 🤔
l
I don’t want to spin off new coroutines because I want to make sure all this communication with JS happens synchronously, but in the background.
Launching a new coroutine or running the code in the same coroutine using
withContext
(or the invoke operator) doesn't impact anything when it comes the dispatcher. Even coroutines have nothing to do with the problem you're facing as Anton said. It's fine to use them here since it seems they are relevant to your use case (waiting for some code to run on a given dispatcher without blocking the main thread). I think you simply need to keep a reference to the executor service so you can close/shutdown it at the end of your
main
function, so the JVM doesn't stay alive.
z
are you referring to
Mutex
, for example? 🤔
Sure, although it’s similar to non-coroutine mutex. More so things like channels, which have a nice api for passing messages between threads. Stuff you can do with non-coroutine primitives too, but it’s nice that these are shipped in what is effectively a standard library extension, supported on multiplatform, etc.