Hey so, If I'm writing a desktop CLI application, ...
# coroutines
g
Hey so, If I'm writing a desktop CLI application, and I want a
Dispatchers.Main
but dont want to put
javafx
on my classloader, what are my options? Do I have any, or do i need to roll my own
MainCoroutineDispatcher
implementation and insert it in the SPI/service-loader?
m
The
Dispatchers.Main
comes in via
Copy code
implementation(libs.kotlinx.coroutines.swing)
which has nothing to do with JavaFX, or did I misunderstand your question?
g
not quite, that is another Main dispatcher, there are several, and they're mostly defined by the service loader interface
MainDispatcherFactory
, https://github.com/Kotlin/kotlinx.coroutines/blob/5d4954b17ac18c572e22a9a6e7bb4e43[…]nx-coroutines-core/common/src/internal/MainDispatcherFactory.kt The thing im noticing is that it only exists for UI frameworks (android, javafx, swing, etc). If im writing a desktop CLI app and I want a
Main
(single-threaded for thread-confinement-ee things), and I dont want to depend on a UI framework, what do I do?
m
Ah, I see. I was mentally a bit on the Compose trip and there you only use the Swing one because Compose on desktop builds upon Swing.
l
Just use runBlocking, it will create a dispatcher with the single thread it's blocking, which is the main thread.
☝️ 1
g
My use case: I have several services that are fairly agnostic to where they're being called from. Right now they're called from a GUI, an API, and a CLI. Most of my code is written to return value objects that are they mutated into the model by the caller --which is near the top of the callstack for the GUI/API/CLI, but some older services use big ol' mutable state. For these, they wrap their state mutations in
withContext(Dispatchers.Main)
--trying to use
Main
as a kind of thread confinrement. This works well in the GUI situtation because
Main
is my UI thread which is perfect for thread confinement. But this breaks for the CLI and API. For the CLI i just didnt notice that it was always using the JavaFX event loop. This happened to work in a lot of environments it probably should've failed in; im curios as to how javafx was able to start from a machine without X or GTK installed. But from the API this is a disaster. So: What should I update my state-mutating code to do? How can I give it a `Dispatchers.Main`thats sufficiently thread-confine-ing?
a
Have you considered using something like
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
? This will give you a single-threaded coroutine dispatcher, much like
Dispatchers.Main
. Though if you really want to just make sure that something is not called concurrently, why not use a Mutex instead?
e
if you're agnostic to which thread you're running on, but simply want to dispatch things sequentially, you can use a view such as
Dispatchers.Default.limitedParallelism(1)
instead of creating a whole new dispatcher and thread pool