2026-11-02 08:19:04 +00:00
|
|
|
//! Value contracts for the single-worker actor prototype.
|
|
|
|
|
|
2026-11-02 09:08:49 +00:00
|
|
|
use runa_core::ImplementationId;
|
2026-11-02 14:19:25 +00:00
|
|
|
use std::fmt;
|
2026-11-02 09:08:49 +00:00
|
|
|
|
2026-11-02 14:19:25 +00:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
|
|
|
pub struct ActorRef([u8; 21]);
|
|
|
|
|
|
|
|
|
|
impl ActorRef {
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
Self::parse(&nanoid::nanoid!()).expect("Nano ID uses the supported alphabet")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn as_str(&self) -> &str {
|
|
|
|
|
std::str::from_utf8(&self.0).expect("Nano ID is valid UTF-8")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn parse(value: &str) -> Option<Self> {
|
|
|
|
|
if value.len() != 21
|
|
|
|
|
|| !value
|
|
|
|
|
.bytes()
|
|
|
|
|
.all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-'))
|
|
|
|
|
{
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
let mut bytes = [0; 21];
|
|
|
|
|
bytes.copy_from_slice(value.as_bytes());
|
|
|
|
|
Some(Self(bytes))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for ActorRef {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self::new()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Debug for ActorRef {
|
|
|
|
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
write!(formatter, "@{}", self.as_str())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for ActorRef {
|
|
|
|
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
formatter.write_str(self.as_str())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::ActorRef;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn generated_actor_references_are_parseable_and_display_without_prefix() {
|
|
|
|
|
let actor_ref = ActorRef::new();
|
|
|
|
|
let parsed = ActorRef::parse(actor_ref.as_str()).expect("generated reference is valid");
|
|
|
|
|
|
|
|
|
|
assert_eq!(parsed, actor_ref);
|
|
|
|
|
assert_eq!(actor_ref.to_string().len(), 21);
|
|
|
|
|
assert_eq!(format!("{actor_ref:?}"), format!("@{actor_ref}"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn parsing_rejects_references_outside_the_url_safe_nanoid_shape() {
|
|
|
|
|
assert!(ActorRef::parse("too-short").is_none());
|
|
|
|
|
assert!(ActorRef::parse("abcdefghijklmnopqrstu!").is_none());
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-11-02 08:19:04 +00:00
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
|
|
pub struct MailboxId(pub u64);
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
|
pub struct Message {
|
|
|
|
|
pub kind: i64,
|
|
|
|
|
pub value: i64,
|
2026-11-02 14:19:25 +00:00
|
|
|
pub target_ref: Option<ActorRef>,
|
2026-11-02 08:19:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
pub enum Status {
|
|
|
|
|
Idle,
|
|
|
|
|
Running,
|
|
|
|
|
Awaiting,
|
2026-11-02 11:35:29 +00:00
|
|
|
Paused,
|
2026-11-02 08:19:04 +00:00
|
|
|
Stopped,
|
|
|
|
|
Failed(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct ActorSnapshot {
|
2026-11-02 14:19:25 +00:00
|
|
|
pub actor_ref: ActorRef,
|
2026-11-02 08:19:04 +00:00
|
|
|
pub mailbox: MailboxId,
|
|
|
|
|
pub implementation: ImplementationId,
|
|
|
|
|
pub incarnation: u64,
|
|
|
|
|
pub state: i64,
|
|
|
|
|
pub status: Status,
|
2026-11-02 12:11:11 +00:00
|
|
|
pub execution: Option<ExecutionSnapshot>,
|
2026-11-02 08:19:04 +00:00
|
|
|
pub queued: Vec<Message>,
|
|
|
|
|
pub reserved: Option<Message>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-11-02 12:11:11 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
|
pub struct ExecutionSnapshot {
|
|
|
|
|
pub vm_steps: u64,
|
|
|
|
|
pub instruction_pointer: usize,
|
|
|
|
|
pub call_depth: usize,
|
|
|
|
|
}
|
|
|
|
|
|
2026-11-02 08:19:04 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub enum Event {
|
2026-11-02 14:19:25 +00:00
|
|
|
Spawned(ActorRef),
|
|
|
|
|
Committed(ActorRef),
|
|
|
|
|
Failed(ActorRef, String),
|
|
|
|
|
Stopped(ActorRef),
|
|
|
|
|
Restarted(ActorRef),
|
|
|
|
|
Paused(ActorRef),
|
|
|
|
|
Resumed(ActorRef),
|
|
|
|
|
InvocationCancelled(ActorRef),
|
|
|
|
|
BehaviorInstalled(ActorRef, ImplementationId),
|
|
|
|
|
StateMigrated(ActorRef, i64, i64),
|
2026-11-02 08:19:04 +00:00
|
|
|
}
|