fitermay
02/02/2023, 7:10 PMCasey Brooks
02/02/2023, 7:15 PMactor { }
function is little more than a Channel
, so that could be the basis for your own implementation of an Actor patternfitermay
02/02/2023, 7:17 PMCasey Brooks
02/02/2023, 7:21 PMactor
API itself wasn’t really designed to handle all the use-cases of Actors properly, either.
There’s been an open issue to create a robust actor framework for many years, but it’s basically on hold indefinitely. So some folks do choose to keep using the actor
function because it’s been said that it’s not going to get removed until/if a proper replacement does come. But at the same time, since there’s so little to those APIs, its’ easy enough that you may want to create your own set of APIs based around Channels to future-proof yourself in the case that it does get removed eventually.ephemient
02/02/2023, 7:22 PMactor()
used to give you, there wasn't anything magic thereCasey Brooks
02/02/2023, 7:25 PMactor
function, this is pretty much all you’d need for a full replacement of that function. Again, there’s nothing magic here
public fun <T> CoroutineScope.actor(block: suspend (ReceiveChannel<T>)->Unit): SendChannel<T> {
val channel = Channel<T>(Channel.RENDEZVOUS)
launch {
block(channel)
}
return channel
}
ephemient
02/02/2023, 8:01 PMactor()
or consume()
do, but conceptually it's thereactor()
behaves (since consume()
also cancels the channel when the block completes or is cancelled)
fun <E> CoroutineScope.actor(
context: CoroutineContext = EmptyCoroutineContext,
capacity: Int = 0,
start: CoroutineStart = CoroutineStart.DEFAULT,
onCompletion: CompletionHandler? = null,
block: suspend ReceiveChannel<E>.() -> Unit,
): SendChannel<E> {
val channel = Channel<E>(capacity)
val job = launch(context, start) {
channel.consume { block() }
}
if (onCompletion != null) job.invokeOnCompletion(onCompletion)
return channel
}
although it doesn't handle start = CoroutineStart.LAZY
and the original implementation does