crb-superagent 0.0.30

CRB | Composable Runtime Blocks | Agent Extensions
Documentation
use super::{Fetcher, Interplay};
use anyhow::Result;
use async_trait::async_trait;
use crb_agent::{Address, Agent, Context, MessageFor};
use crb_core::time::Instant;

pub trait PingExt {
    fn ping(&self) -> Fetcher<Pong>;
}

impl<A: Agent> PingExt for Address<A> {
    fn ping(&self) -> Fetcher<Pong> {
        let now = Instant::now();
        let (interplay, fetcher) = Interplay::new_pair(now);
        let msg = Ping { interplay };
        let res = self.send(msg);
        fetcher.grasp(res)
    }
}

impl<A: Agent> PingExt for Context<A> {
    fn ping(&self) -> Fetcher<Pong> {
        self.address().ping()
    }
}

pub struct Ping {
    pub interplay: Interplay<Instant, Pong>,
}

pub struct Pong {
    pub ping: Instant,
    pub pong: Instant,
}

#[async_trait]
impl<A: Agent> MessageFor<A> for Ping {
    async fn handle(self: Box<Self>, _agent: &mut A, _ctx: &mut Context<A>) -> Result<()> {
        let ping = self.interplay.request;
        let pong = Instant::now();
        self.interplay.responder.send(Pong { ping, pong })
    }
}