ractor/actor/actor_id.rs
1// Copyright (c) Sean Lawlor
2//
3// This source code is licensed under both the MIT license found in the
4// LICENSE-MIT file in the root directory of this source tree.
5
6//! This module handles everything around actor id's. In the event you have a
7//! remote actor, the actor's ID will denote not only the actor's instance id, but
8//! the id of the remote node the actor is running on.
9//!
10//! ActorIds are generally helpful in logging and pattern matching, but not directly
11//! used in addressing outside of `ractor_cluster` network-based call internals.
12
13use std::fmt::Display;
14use std::sync::atomic::AtomicU64;
15
16/// An actor's globally unique identifier
17#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
18pub enum ActorId {
19 /// A local pid
20 Local(u64),
21
22 /// A remote actor on another system (system, id)
23 Remote {
24 /// The remote node id
25 node_id: u64,
26 /// The local id on the remote system
27 pid: u64,
28 },
29}
30
31impl ActorId {
32 /// Determine if this actor id is a local or remote actor
33 ///
34 /// Returns [true] if it is a local actor, [false] otherwise
35 pub const fn is_local(&self) -> bool {
36 matches!(self, ActorId::Local(_))
37 }
38
39 /// Retrieve the actor's PID
40 ///
41 /// Returns the actor's [u64] instance identifier (process id).
42 pub const fn pid(&self) -> u64 {
43 match self {
44 ActorId::Local(pid) => *pid,
45 ActorId::Remote { pid, .. } => *pid,
46 }
47 }
48
49 /// Retrieve the node id of this PID. 0 = a local actor, while
50 /// any non-zero value is the ide of the remote node running this actor
51 pub const fn node(&self) -> u64 {
52 match self {
53 ActorId::Local(_) => 0,
54 ActorId::Remote { node_id, .. } => *node_id,
55 }
56 }
57}
58
59impl Display for ActorId {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 match self {
62 ActorId::Local(id) => write!(f, "0.{id}"),
63 ActorId::Remote { node_id, pid } => write!(f, "{node_id}.{pid}"),
64 }
65 }
66}
67
68/// The local id allocator for actors
69static ACTOR_ID_ALLOCATOR: AtomicU64 = AtomicU64::new(0u64);
70
71/// Retrieve a new local id
72pub(crate) fn get_new_local_id() -> ActorId {
73 ActorId::Local(ACTOR_ID_ALLOCATOR.fetch_add(1, std::sync::atomic::Ordering::AcqRel))
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_pid() {
82 let actor_id = ActorId::Local(123);
83 assert_eq!(123, actor_id.pid());
84 let actor_id = ActorId::Remote {
85 node_id: 1,
86 pid: 123,
87 };
88 assert_eq!(123, actor_id.pid());
89 }
90
91 #[test]
92 fn test_is_local() {
93 let actor_id = ActorId::Local(123);
94 assert!(actor_id.is_local());
95 let actor_id = ActorId::Remote {
96 node_id: 1,
97 pid: 123,
98 };
99 assert!(!actor_id.is_local());
100 }
101}