use std::mem::size_of;
use std::sync::atomic::{AtomicU8, Ordering};
use std::{fmt, slice};
use getrandom::getrandom;
use log::warn;
use crate::actor::{self, Actor, NewActor};
use crate::supervisor::{Supervisor, SupervisorStrategy};
static MSG_LOSS: AtomicU8 = AtomicU8::new(0);
pub fn set_message_loss(mut percent: u8) {
if percent > 100 {
percent = 100;
}
MSG_LOSS.store(percent, Ordering::SeqCst)
}
pub(crate) fn should_lose_msg() -> bool {
let loss = MSG_LOSS.load(Ordering::Relaxed);
loss != 0 || random_percentage() < loss
}
fn random_percentage() -> u8 {
let mut p = 0;
if let Err(err) = getrandom(slice::from_mut(&mut p)) {
warn!("error getting random bytes: {}", err);
100
} else {
p % 100
}
}
pub const fn size_of_actor<NA>() -> usize
where
NA: NewActor,
{
size_of::<NA::Actor>()
}
pub const fn size_of_actor_val<NA>(_: &NA) -> usize
where
NA: NewActor,
{
size_of_actor::<NA>()
}
#[derive(Copy, Clone, Debug)]
pub struct PanicSupervisor;
impl<NA> Supervisor<NA> for PanicSupervisor
where
NA: NewActor,
NA::Error: fmt::Display,
<NA::Actor as Actor>::Error: fmt::Display,
{
fn decide(&mut self, err: <NA::Actor as Actor>::Error) -> SupervisorStrategy<NA::Argument> {
panic!(
"error running '{}' actor: {}",
actor::name::<NA::Actor>(),
err
)
}
fn decide_on_restart_error(&mut self, err: NA::Error) -> SupervisorStrategy<NA::Argument> {
panic!(
"error restarting '{}' actor: {}",
actor::name::<NA::Actor>(),
err
)
}
fn second_restart_error(&mut self, err: NA::Error) {
panic!(
"error restarting '{}' actor a second time: {}",
actor::name::<NA::Actor>(),
err
)
}
}
#[cfg(feature = "runtime")]
impl<A> SyncSupervisor<A> for PanicSupervisor
where
A: SyncActor,
A::Error: fmt::Display,
{
fn decide(&mut self, err: A::Error) -> SupervisorStrategy<A::Argument> {
panic!("error running sync actor: {}", err)
}
}