-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
What do we have now?
I want to return a CompletableDeferred<T>
from a public API. I am returning it as a Deferred<T>
as I don't want the consumer of the API to be able to complete the deferred, as this would mess with the internals class returning the deferred. If I just return the CompletableDeferred<T>
, it can still be tempting for a consumer to upcast Deferred<T>
to CompletableDeferred<T>
and complete it.
So I do the following instead:
private class ReadOnlyDeferred<T>(source: Deferred<T>) : Deferred<T> by source
fun <T> execute(): Deferred<T> {
// some code
return ReadOnlyDeferred(result)
}
This would be a clean solution, but unfortunately I get this warning:
This class or interface requires opt-in to be implemented: This is a kotlinx. coroutines API that is not intended to be inherited from, as the library may handle predefined instances of this in a special manner. This will be an error in a future release. If you need to inherit from this, please describe your use case in https:// github. com/ Kotlin/ kotlinx. coroutines/ issues, so that we can provide a stable API for inheritance.
What should be instead?
There should be a way to achieve the above scenario without relying on internal APIs. Either provide a function allowing to return a "locked" version of the deferred:
fun <T> Deferred<T>.lock(): Deferred<T>
This is similar to CompletableFuture<T>.minimalCompletionStage()
.
Or remove InternalForInheritanceCoroutinesApi
from Deferred<T>
.
Why?
This would allow basic encapsulation for Deferred.
Activity
Introduce CompletableDeferred.asDeferred that prevents downcasting
Introduce CompletableDeferred.asDeferred that prevents downcasting
dkhalanskyjb commentedon Apr 9, 2025
Thanks! The use case is clear, and we already have things like https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/as-state-flow.html, so adding this is straightforward: #4410
Flavien commentedon Apr 9, 2025
Wow, that was fast, thanks @dkhalanskyjb .
Introduce CompletableDeferred.asDeferred that prevents downcasting (#…
Introduce CompletableDeferred.asDeferred that prevents downcasting (#…