#![deny(unsafe_code)]
#![warn(missing_docs)]
#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
pub mod error;
mod executor;
mod handle;
mod mailbox;
#[cfg(feature = "unsafe-pool")]
pub mod memory_pool;
pub mod policy;
pub mod queue;
mod registry;
#[cfg(feature = "serde")]
pub mod rpc;
mod scheduler;
#[cfg_attr(feature = "sim", allow(clippy::unwrap_used))]
#[cfg(feature = "sim")]
pub mod sim;
pub mod supervisor;
#[cfg(feature = "zero-copy")]
pub mod zero_copy;
pub use error::{Error, Result};
pub use executor::{ActorExecutor, ExecutionResult, NullExecutor};
pub use handle::{ActorBuilder, ActorHandle};
pub use mailbox::{Mailbox, MailboxConfig};
pub use policy::{NoopPolicy, ResourcePolicy};
pub use queue::{create_local_queue, PriorityQueue, WorkQueue, WorkStealer};
pub use registry::{ActorRegistry, ActorState, RegistryStats};
#[cfg(feature = "serde")]
pub use rpc::{
process_rpc_message, RpcClient, RpcEnvelope, RpcError, RpcHandler, RpcMessage, RpcRegistry,
RpcRequest, RpcResponse,
};
pub use scheduler::{
ActorScheduler, SchedulerConfig, SchedulerStats, StealerRegistry, WorkerStatsInfo,
};
pub use supervisor::{
ActorConfig, ChildSpec, ChildState, DegradationController, DegradationDecision,
EscalationAction, ExitReason, FnResourceMonitor, PressureLevel, ResourceMonitor, RestartPolicy,
StaticResourceMonitor, SupervisedChild, SupervisionStrategy, Supervisor, SupervisorError,
SupervisorHandle, SupervisorStats, SupervisorTree, SupervisorTreeStats,
};
use std::sync::Arc;
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ActorId(pub Uuid);
impl ActorId {
pub fn new() -> Self {
Self(Uuid::new_v4())
}
}
impl Default for ActorId {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub enum Priority {
Low = 0,
#[default]
Normal = 1,
High = 2,
Critical = 3,
}
#[derive(Debug, Clone)]
pub struct Message {
pub sender: Option<ActorId>,
pub payload: MessagePayload,
pub priority: Priority,
}
impl Default for Message {
fn default() -> Self {
Self {
sender: None,
payload: MessagePayload::Empty,
priority: Priority::Normal,
}
}
}
#[derive(Debug, Clone, Default)]
pub enum MessagePayload {
Start,
Stop,
Custom(Vec<u8>),
Signal(Signal),
#[default]
Empty,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Signal {
Pause,
Resume,
Restart,
}
pub trait Actor: Send + Sync + 'static {
fn handle(
&mut self,
msg: Message,
ctx: &ActorContext,
) -> impl std::future::Future<Output = Result<()>> + Send;
}
pub struct ActorContext {
pub id: ActorId,
scheduler: Arc<ActorScheduler>,
}
impl ActorContext {
pub async fn send(&self, target: ActorId, payload: MessagePayload) -> Result<()> {
self.scheduler
.send(
target,
Message {
sender: Some(self.id),
payload,
priority: Priority::Normal,
},
)
.await
}
pub async fn send_high(&self, target: ActorId, payload: MessagePayload) -> Result<()> {
self.scheduler
.send(
target,
Message {
sender: Some(self.id),
payload,
priority: Priority::High,
},
)
.await
}
}
#[doc(hidden)]
#[allow(clippy::expect_used)] pub fn rt() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("failed to build runtime")
}