extern crate riker; use riker::actors::*; use std::time::Duration; #[derive(Clone, Debug)] pub struct Panic; #[derive(Default)] struct DumbActor; impl Actor for DumbActor { type Msg = (); fn recv(&mut self, _: &Context, _: Self::Msg, _: Sender) {} } #[actor(Panic)] #[derive(Default)] struct PanicActor; impl Actor for PanicActor { type Msg = PanicActorMsg; fn pre_start(&mut self, ctx: &Context) { ctx.actor_of::("child_a").unwrap(); ctx.actor_of::("child_b").unwrap(); ctx.actor_of::("child_c").unwrap(); ctx.actor_of::("child_d").unwrap(); } fn recv(&mut self, ctx: &Context, msg: Self::Msg, sender: Sender) { self.receive(ctx, msg, sender); } } impl Receive for PanicActor { type Msg = PanicActorMsg; fn receive(&mut self, _ctx: &Context, _msg: Panic, _sender: Sender) { panic!("// TEST PANIC // TEST PANIC // TEST PANIC //"); } } #[actor(Panic)] #[derive(Default)] struct EscalateSup { actor_to_fail: Option>, } impl Actor for EscalateSup { type Msg = EscalateSupMsg; fn pre_start(&mut self, ctx: &Context) { self.actor_to_fail = ctx.actor_of::("actor-to-fail").ok(); } fn supervisor_strategy(&self) -> Strategy { Strategy::Escalate } fn recv(&mut self, ctx: &Context, msg: Self::Msg, sender: Sender) { self.receive(ctx, msg, sender); // match msg { // // We just resend the messages to the actor that we're concerned about testing // TestMsg::Panic => self.actor_to_fail.try_tell(msg, None).unwrap(), // TestMsg::Probe(_) => self.actor_to_fail.try_tell(msg, None).unwrap(), // }; } } impl Receive for EscalateSup { type Msg = EscalateSupMsg; fn receive(&mut self, _ctx: &Context, _msg: Panic, _sender: Sender) { self.actor_to_fail.as_ref().unwrap().tell(Panic, None); } } #[actor(Panic)] #[derive(Default)] struct EscRestartSup { escalator: Option>, } impl Actor for EscRestartSup { type Msg = EscRestartSupMsg; fn pre_start(&mut self, ctx: &Context) { self.escalator = ctx.actor_of::("escalate-supervisor").ok(); } fn supervisor_strategy(&self) -> Strategy { Strategy::Restart } fn recv(&mut self, ctx: &Context, msg: Self::Msg, sender: Sender) { self.receive(ctx, msg, sender); // match msg { // // We resend the messages to the parent of the actor that is/has panicked // TestMsg::Panic => self.escalator.try_tell(msg, None).unwrap(), // TestMsg::Probe(_) => self.escalator.try_tell(msg, None).unwrap(), // }; } } impl Receive for EscRestartSup { type Msg = EscRestartSupMsg; fn receive(&mut self, _ctx: &Context, _msg: Panic, _sender: Sender) { self.escalator.as_ref().unwrap().tell(Panic, None); } } fn main() { let sys = ActorSystem::new().unwrap(); let sup = sys.actor_of::("supervisor").unwrap(); println!("Before panic we see supervisor and actor that will panic!"); std::thread::sleep(Duration::from_millis(500)); sys.print_tree(); sup.tell(Panic, None); std::thread::sleep(Duration::from_millis(500)); println!("We should see panic printed, but we still alive and panic actor still here!"); sys.print_tree(); }