Skip to main content

crb_superagent/interplay/
ping.rs

1use super::{Fetcher, Interplay};
2use anyhow::Result;
3use async_trait::async_trait;
4use crb_agent::{Address, Agent, Context, MessageFor};
5use crb_core::time::Instant;
6
7pub trait PingExt {
8    fn ping(&self) -> Fetcher<Pong>;
9}
10
11impl<A: Agent> PingExt for Address<A> {
12    fn ping(&self) -> Fetcher<Pong> {
13        let now = Instant::now();
14        let (interplay, fetcher) = Interplay::new_pair(now);
15        let msg = Ping { interplay };
16        let res = self.send(msg);
17        fetcher.grasp(res)
18    }
19}
20
21impl<A: Agent> PingExt for Context<A> {
22    fn ping(&self) -> Fetcher<Pong> {
23        self.address().ping()
24    }
25}
26
27pub struct Ping {
28    pub interplay: Interplay<Instant, Pong>,
29}
30
31pub struct Pong {
32    pub ping: Instant,
33    pub pong: Instant,
34}
35
36#[async_trait]
37impl<A: Agent> MessageFor<A> for Ping {
38    async fn handle(self: Box<Self>, _agent: &mut A, _ctx: &mut Context<A>) -> Result<()> {
39        let ping = self.interplay.request;
40        let pong = Instant::now();
41        self.interplay.responder.send(Pong { ping, pong })
42    }
43}