arkivanov / Essenty

The most essential libraries for Kotlin Multiplatform development
Apache License 2.0
468 stars 15 forks source link

Make `Dispatchers.immediateOrFallback` public #158

Closed Nek-12 closed 4 months ago

Nek-12 commented 4 months ago

This function is needed to develop custom integrations with Essenty for other libraries that want to provide the same default values for certain APIs as decompose does. For example, creating a function analogous to

fun LifecycleOwner.coroutineScope(
    context: CoroutineContext = Dispatchers.Main.immediateOrFallback,
): CoroutineScope =
    CoroutineScope(context = context).withLifecycle(lifecycle)

Is impossible right now because the default value cannot be retrieved.

Our use-case is such that we want to provide a retained coroutine scope that uses immediate dispatcher by default and we cannot do that unless we copy and paste the code from Essenty.

arkivanov commented 4 months ago

All default values are not part of the public API. E.g. the following function uses immediateOrFallback as implementation details, the value usage is not part of the API.

fun LifecycleOwner.coroutineScope(
    context: CoroutineContext = Dispatchers.Main.immediateOrFallback,
): CoroutineScope 

I think even if we expose Dispatchers.Main.immediateOrFallback from the library and you will start using it, the default value of the context argument may change without any notice - e.g. we may need another "fallback" for that specific function while keeping the current "fallback" for the others. Therefore, assuming that the same immediateOrFallback API is used as a default value in any Essenty implementation details is incorrect.

arkivanov commented 4 months ago

That said, copying the extension to your project would be essentially equivalent.

Nek-12 commented 4 months ago

Copying the extension would introduce the overhead of checking if the immediate dispatcher is supported multiple times. The first time essenty will check for availability and store a static volatile reference, the second time our code will do the same. I'm of opinion that if the library is called "essentials for multiplatform", then having an immediate dispatcher is essential for development.

Keeping up to date with changes to the essenty code, if any, will be the target library developer's responsibility in that case.

That said, I'm open to any other solutions that you may suggest on how to let users have sensible defaults without using these internal implementation details

arkivanov commented 4 months ago

The mentioned extension MainCoroutineDispatcher.immediateOrFallback: MainCoroutineDispatcher is currently located in the lifecycle-coroutines module. Exposing it right there doesn't make sense, because this particular extension has nothing todo with Lifecycle. We would need to introduce a new module (e.g. coroutines) for this API. But for now, I'm not in favour of creating a new module just for this.

I will keep this in mind, but for now please copy the extension into your project if needed.