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.