tiny-actor
Tiny-actor is a minimal actor framework for Rust. Because it tries to stay as minimal as possible, it can be used both in libraries, as well as in applications.
The core priniciple of tiny-actor is merging inboxes with processes. It's impossible to create an inbox without a process, this allows for building simple pools and supervision-trees, with reliable shutdown behaviour.
Concepts
Channel
A channel is that which underlies the coupling of inboxes, addresses and children. A channel contains:
- One
ChildorChildPool - Zero or more
Addresses - Zero or more
Inboxes
Inbox
An Inbox refers is the receiver-part of a Channel, this is always coupled with a tokio::task. The Inbox is
primarily used to take messages out of the Channel.
Inboxes can only be created by spawning new processes and should stay coupled to the tokio::task they were
spawned with. Therefore, an Inbox should only be dropped when the tokio::task is exiting.
Address
An Address is the cloneable sender-part of a Channel. The Address is primarily used to send messages to
Inboxes.
When all Addresses are dropped, the Channel is closed automatically.
Addresses can be awaited, which will return when all Inboxes linked to the Channel have exited.
Child
A Child is a handle to a Channel with a one Inbox. The Child can be awaited to return the exit-value
of the tokio::task that has been spawned. A Child is non-cloneable, and therefore unique to the Channel.
When the Child is dropped, the attached process will be aborted. This can be prevented by detaching
the Child. More processes can be spawned later, which transforms the Child into a ChildPool.
ChildPool
A ChildPool is similar to a Child, except that the Channel can have more than one Inbox.
A ChildPool can be streamed to get the exit-values of all spawned tokio::tasks.
Closing
When a Channel is closed, it is not longer possible to send new messages into it. It is still possible to
take out any messages that are remaining.
A channel that is closed does not have to exit afterwards.
Any senders are notified with a SendError::Closed. Receivers will receive RecvError::ClosedAndEmpty once
the channel has been emptied.
Halting
An Inbox can be halted exactly once. When receiving a RecvError::Halted the process should exit.
A Channel can be partially halted, meaning that only some of the Inboxes have been halted.
Aborting
A process can be aborted through tokio's abort method.This causes the process to exit abruptly, and can leave bad state behind. Wherever possible, use halt instead
of abort.
By default, a spawned process is automatically aborted when the Child is dropped. This can be prevented by
detaching a Child.
Exiting
Exit can refer to two seperate events which, with good practise, always occur at the same time:
- An
Inboxcan exit by being dropped. Once allInboxes of aChannelhave been dropped, theChannelitself has exited. This type of exit can be retrieved/awaited from theChannelat any time. - A
tokio::taskcan exit, which means the process is no longer alive. This can only be queried only once, by awaiting theChildorChildPool. Therefore, it is recommended to drop anInboxonly when the process itself is also exiting. This way, an exit always refers to the same event.
Abort-timer
A Child or ChildPool has an abort-timer. If the Child or ChildPool is attached, then it will instantly
send a Halt-signal to all inboxes. Then, after the abort-timer, if the child still has not exited, it will be
aborted.
Examples
Basic
use *;
async
Pooled with config
use *;
use Duration;
use StreamExt;
async