arrow-fx-coroutines / arrow.fx.coroutines / cancellableF
suspend fun <A> ~~cancellableF~~(cb: suspend ((
Result
<A>) ->
Unit
) ->
CancelToken
): A
Deprecated: Use suspendCancellableCoroutine
Creates a cancellable suspend
function that executes an asynchronous process on evaluation.
This combinator can be used to wrap callbacks or other similar impure code that requires cancellation code.
The suspending cb runs in an uncancellable manner, acquiring CancelToken as a resource. If cancellation signal is received while cb is running, then the CancelToken will be triggered as soon as it’s returned.
import arrow.core.*
import arrow.fx.coroutines.*
import java.lang.RuntimeException
import kotlin.coroutines.Continuation
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.startCoroutine
typealias Callback = (List<String>?, Throwable?) -> Unit
class GithubId
object GithubService {
private val listeners: MutableMap<GithubId, Fiber<*>> = mutableMapOf()
suspend fun getUsernames(callback: Callback): GithubId {
val id = GithubId()
val fiber = ForkConnected { sleep(2.seconds); callback(listOf("Arrow"), null) }
listeners[id] = fiber
return id
}
fun unregisterCallback(id: GithubId): Unit {
suspend { listeners[id]?.cancel() }
.startCoroutine(Continuation(EmptyCoroutineContext) { }) // Launch and forget
listeners.remove(id)
}
}
suspend fun main(): Unit {
//sampleStart
suspend fun getUsernames(): List<String> =
cancellableF { cb: (Result<List<String>>) -> Unit ->
val id = GithubService.getUsernames { names, throwable ->
when {
names != null -> cb(Result.success(names))
throwable != null -> cb(Result.failure(throwable))
else -> cb(Result.failure(RuntimeException("Null result and no exception")))
}
}
CancelToken { GithubService.unregisterCallback(id) }
}
val result = getUsernames()
//sampleEnd
println(result)
}
cb
- an asynchronous computation that might fail.
See Also
Do you like Arrow?
✖