model.rs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //! This module contains types used to model the actor system implemented by the runtime.
  2. use std::{fmt::Display, sync::Arc};
  3. use btlib::BlockPath;
  4. use btserde::field_helpers::smart_ptr;
  5. use serde::{de::DeserializeOwned, Deserialize, Serialize};
  6. use uuid::Uuid;
  7. /// Represents the result of an actor state transition, which can be one of the following:
  8. /// * `Success`: The transition succeeded and the new state is contained in the result.
  9. /// * `Abort`: The transition failed and the previous state along with an error describing
  10. /// the failure is in the result.
  11. /// * `Fatal`: The transition failed and the actor cannot recover from this failure. An error
  12. /// describing the failure is contained in the result.
  13. pub enum TransResult<From, To> {
  14. /// Represents a successful transition.
  15. Ok(To),
  16. /// Represents an aborted transition.
  17. Abort { from: From, err: btlib::Error },
  18. /// Represents a failed transition which kills the actor which attempted it.
  19. Fatal { err: btlib::Error },
  20. }
  21. /// Specifies a kind of transition, either a `Send` or a `Receive`.
  22. pub enum TransKind {
  23. /// A transition which doesn't receive any message, but sends one or more.
  24. Send,
  25. /// A transition which receives a message.
  26. Receive,
  27. }
  28. impl TransKind {
  29. const fn verb(&self) -> &'static str {
  30. match self {
  31. Self::Send => "sending",
  32. Self::Receive => "receiving",
  33. }
  34. }
  35. }
  36. /// A struct which conveys information about where an actor panic occurred to the kernel.
  37. pub struct ActorPanic {
  38. /// The name of the actor implementation which panicked.
  39. pub actor_impl: String,
  40. /// The name of the state the actor was in.
  41. pub state: &'static str,
  42. /// The name of the message the actor was handling, or the name of the first message it was
  43. /// trying to send.
  44. pub message: &'static str,
  45. /// The kind of transition which was being attempted.
  46. pub kind: TransKind,
  47. /// An error describing why the panic occurred.
  48. pub err: btlib::Error,
  49. }
  50. impl Display for ActorPanic {
  51. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  52. write!(
  53. f,
  54. "Actor {} panicked in state {} while {} a message of type {}: {}",
  55. self.actor_impl,
  56. self.state,
  57. self.kind.verb(),
  58. self.message,
  59. self.err
  60. )
  61. }
  62. }
  63. /// Represents the terminal state of an actor, where it stops processing messages and halts.
  64. pub struct End;
  65. impl End {
  66. /// Returns the identifier for this type which is expected in protocol definitions.
  67. pub fn ident() -> &'static str {
  68. stringify!(End)
  69. }
  70. }
  71. /// A unique identifier for a particular service.
  72. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
  73. pub struct ServiceId(#[serde(with = "smart_ptr")] Arc<String>);
  74. impl ServiceId {
  75. pub fn new(value: Arc<String>) -> Self {
  76. Self(value)
  77. }
  78. }
  79. impl AsRef<str> for ServiceId {
  80. fn as_ref(&self) -> &str {
  81. self.0.as_str()
  82. }
  83. }
  84. impl<T: Into<String>> From<T> for ServiceId {
  85. fn from(value: T) -> Self {
  86. Self(Arc::new(value.into()))
  87. }
  88. }
  89. impl Display for ServiceId {
  90. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  91. f.write_str(self.as_ref())
  92. }
  93. }
  94. /// A unique identifier for a service.
  95. ///
  96. /// A service is a collection of actors in the same directory which provide some functionality.
  97. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
  98. pub struct ServiceName {
  99. /// The path to the directory containing the service.
  100. #[serde(with = "smart_ptr")]
  101. path: Arc<BlockPath>,
  102. /// The id of the service.
  103. service_id: ServiceId,
  104. }
  105. impl ServiceName {
  106. pub fn new(path: Arc<BlockPath>, service_id: ServiceId) -> Self {
  107. Self { path, service_id }
  108. }
  109. }
  110. /// Indicates the set of service providers a message is addressed to.
  111. ///
  112. /// The message could be delivered to any of the service providers in this set, at random.
  113. pub struct ServiceAddr {
  114. /// The [ServiceName] to address the message to.
  115. name: ServiceName,
  116. #[allow(dead_code)]
  117. /// Indicates if the message should be routed towards the root of the tree or away from it.
  118. rootward: bool,
  119. }
  120. impl ServiceAddr {
  121. pub fn new(name: ServiceName, rootward: bool) -> Self {
  122. Self { name, rootward }
  123. }
  124. pub fn path(&self) -> &Arc<BlockPath> {
  125. &self.name.path
  126. }
  127. pub fn service_id(&self) -> &ServiceId {
  128. &self.name.service_id
  129. }
  130. }
  131. /// An identifier for an actor which is unique in a given runtime.
  132. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
  133. pub struct ActorId(Uuid);
  134. impl ActorId {
  135. pub fn new() -> Self {
  136. Self(Uuid::new_v4())
  137. }
  138. /// Returns an actor ID that can't have messages delivered to it.
  139. pub fn undeliverable() -> Self {
  140. Self(Uuid::from_bytes([0; 16]))
  141. }
  142. }
  143. impl Default for ActorId {
  144. fn default() -> Self {
  145. Self::new()
  146. }
  147. }
  148. impl Copy for ActorId {}
  149. impl Display for ActorId {
  150. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  151. self.0.fmt(f)
  152. }
  153. }
  154. /// A unique identifier for a specific actor activation.
  155. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
  156. pub struct ActorName {
  157. /// The path to the directory containing this actor.
  158. #[serde(with = "smart_ptr")]
  159. path: Arc<BlockPath>,
  160. /// A unique identifier for an actor activation. Even as an actor transitions to different types
  161. /// as it handles messages, this value does not change. Thus this value can be used to trace an
  162. /// actor through a series of state transitions.
  163. act_id: ActorId,
  164. }
  165. impl ActorName {
  166. pub fn new(path: Arc<BlockPath>, act_id: ActorId) -> Self {
  167. Self { path, act_id }
  168. }
  169. pub fn path(&self) -> &Arc<BlockPath> {
  170. &self.path
  171. }
  172. pub fn act_id(&self) -> ActorId {
  173. self.act_id
  174. }
  175. }
  176. impl Display for ActorName {
  177. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  178. write!(f, "{}@{}", self.act_id, self.path)
  179. }
  180. }
  181. /// Trait for messages which expect exactly one reply.
  182. pub trait CallMsg: Serialize + DeserializeOwned + Send + Sync {
  183. /// The reply type expected for this message.
  184. type Reply: Serialize + DeserializeOwned + Send + Sync;
  185. }
  186. /// Trait for messages which expect exactly zero replies.
  187. pub trait SendMsg: CallMsg {}
  188. /// A type used to express when a reply is not expected for a message type.
  189. #[derive(Serialize, Deserialize)]
  190. pub enum NoReply {}