crb_agent/message/
interrupt.rs

1use crate::address::{Address, MessageFor};
2use crate::agent::Agent;
3use crate::context::Context;
4use anyhow::Result;
5use async_trait::async_trait;
6use crb_runtime::{InterruptionLevel, Interruptor};
7
8impl<A: Agent> Address<A> {
9    pub fn interrupt(&self) -> Result<()> {
10        self.send(Interrupt)
11    }
12}
13
14struct Interrupt;
15
16#[async_trait]
17impl<A: Agent> MessageFor<A> for Interrupt {
18    async fn handle(self: Box<Self>, agent: &mut A, ctx: &mut Context<A>) -> Result<()> {
19        let name = std::any::type_name::<A>();
20        log::trace!("Interrupting agent: {name}");
21        agent.interrupt(ctx);
22        Ok(())
23    }
24}
25
26impl<A: Agent> Interruptor for Address<A> {
27    fn interrupt(&self) {
28        self.interrupt_with_level(InterruptionLevel::FLAG);
29    }
30
31    fn interrupt_with_level(&self, level: InterruptionLevel) {
32        if level >= InterruptionLevel::EVENT {
33            // 0 - Interrupts an actor
34            Address::interrupt(self).ok();
35        }
36        if level >= InterruptionLevel::FLAG {
37            // 1 - Interrupts a state-machine
38            self.stopper().stop(false);
39        }
40        if level >= InterruptionLevel::ABORT {
41            // 2 - Interrupts an async routine
42            self.stopper().stop(true);
43        }
44    }
45}