vertep_runtime/placement.rs
1//! The placement hook of a clustered node.
2//!
3//! A single node hosts every virtual actor whose chart type it knows. In a cluster, each
4//! virtual actor lives on the node that leases its shard, so the node asks a [`Placement`]
5//! where an actor lives before it delivers a message to it or activates it. Without a
6//! placement (the default), the node behaves exactly as a single node.
7//!
8//! The answer is a [`Route`]:
9//!
10//! - [`Route::Local`]: this node hosts the actor now; deliver and activate as usual.
11//! - [`Route::Remote`]: another node hosts it; the message goes into the given mailbox, which
12//! carries it there. Messages already waiting in the local mailbox are moved there too, and
13//! an activation on this node is deactivated first.
14//! - [`Route::Hold`]: no node may host it now (its shard is unowned or its owner is gone); the
15//! message waits in the local mailbox and the actor is not activated.
16//!
17//! [`Placement::route`] sees every message to a virtual actor or a stateless worker before it
18//! is delivered, so a cluster can also balance worker requests and observe their replies.
19//!
20//! @tg: implements:: [[decisions#Placement is a runtime hook with three answers]]
21
22use std::sync::Arc;
23
24use crate::address::Address;
25use crate::mailbox::{Envelope, Mailbox};
26
27/// Where an actor lives now.
28#[derive(Clone)]
29pub enum Route {
30 /// On this node.
31 Local,
32 /// On another node, reached through this mailbox.
33 Remote(Arc<dyn Mailbox>),
34 /// Nowhere yet: keep the message here and do not activate the actor.
35 Hold,
36}
37
38impl std::fmt::Debug for Route {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 match self {
41 Route::Local => f.write_str("Local"),
42 Route::Remote(_) => f.write_str("Remote"),
43 Route::Hold => f.write_str("Hold"),
44 }
45 }
46}
47
48/// Decides where virtual actors and stateless workers live in a cluster.
49pub trait Placement: Send + Sync {
50 /// Where the actor at `to` lives, for delivering `env` (`None` when the node asks before
51 /// activating `to`, with no message in hand). `virtual_actor` is true when this node knows
52 /// `to` as a virtual actor (its chart type is registered or it has a journal here); the
53 /// node also asks for stateless workers and for addresses it does not know, which a
54 /// cluster may host elsewhere. [`Route::Local`] for an address the node does not know
55 /// sends it on to the directory.
56 fn route(&self, to: &Address, virtual_actor: bool, env: Option<&Envelope>) -> Route;
57}