actor

fun <E> CoroutineScope.actor(context: CoroutineContext = EmptyCoroutineContext, capacity: Int = 0, start: CoroutineStart = CoroutineStart.DEFAULT, onCompletion: CompletionHandler? = null, block: suspend ActorScope<E>.() -> Unit): SendChannel<E>(source)

Launches new coroutine that is receiving messages from its mailbox channel and returns a reference to its mailbox channel as a SendChannel. The resulting object can be used to send messages to this coroutine.

The scope of the coroutine contains ActorScope interface, which implements both CoroutineScope and ReceiveChannel, so that coroutine can invoke receive directly. The channel is closed when the coroutine completes.

Coroutine context is inherited from a CoroutineScope, additional context elements can be specified with context argument. If the context does not have any dispatcher nor any other ContinuationInterceptor, then Dispatchers.Default is used. The parent job is inherited from a CoroutineScope as well, but it can also be overridden with corresponding context element.

By default, the coroutine is immediately scheduled for execution. Other options can be specified via start parameter. See CoroutineStart for details. An optional start parameter can be set to CoroutineStart.LAZY to start coroutine lazily. In this case, it will be started implicitly on the first message sent to this actors's mailbox channel.

Uncaught exceptions in this coroutine close the channel with this exception as a cause and the resulting channel becomes failed, so that any attempt to send to such a channel throws exception.

The kind of the resulting channel depends on the specified capacity parameter. See Channel interface documentation for details.

See newCoroutineContext for a description of debugging facilities that are available for newly created coroutine.

Using actors

A typical usage of the actor builder looks like this:

val c = actor {
// initialize actor's state
for (msg in channel) {
// process message here
}
}
// send messages to the actor
c.send(...)
...
// stop the actor when it is no longer needed
c.close()

Stopping and cancelling actors

When the inbox channel of the actor is closed it sends a special "close token" to the actor. The actor still processes all the messages that were already sent and then "for (msg in channel)" loop terminates and the actor completes.

If the actor needs to be aborted without processing all the messages that were already sent to it, then it shall be created with a parent job:

val job = Job()
val c = actor(context = job) { ... }
...
// abort the actor
job.cancel()

When actor's parent job is cancelled, then actor's job becomes cancelled. It means that "for (msg in channel)" and other cancellable suspending functions throw CancellationException and actor completes without processing remaining messages.

Note: This API will become obsolete in future updates with introduction of complex actors. See issue #87.

Parameters

context

additional to CoroutineScope.coroutineContext context of the coroutine.

capacity

capacity of the channel's buffer (no buffer by default).

start

coroutine start option. The default value is CoroutineStart.DEFAULT.

onCompletion

optional completion handler for the actor coroutine (see Job.invokeOnCompletion)

block

the coroutine code.