use futures::{future, prelude::*}; use holly::{Error, prelude::*}; use tokio_threadpool::ThreadPool; // The root actor. struct Root; // Messages the root actor accepts. enum RootMsg { Start, FromChild(Hello) } impl From for RootMsg { fn from(h: Hello) -> Self { RootMsg::FromChild(h) } } // The child actor, created by `Root`. struct Child { // The child knows its parent address, but can only send back `Hello` messages. parent: Addr } // Message, the child actor receives. struct ChildMsg; // Message from child to parent. #[derive(Debug)] struct Hello; impl Actor for Root { type Result = Box, Error = Error> + Send>; fn process(self, ctx: &mut Context, msg: Option) -> Self::Result { match msg { Some(RootMsg::Start) => { let child = Child { parent: ctx.address().cast() }; let future = future::result(ctx.scheduler().spawn(child)) .and_then(|addr| addr.send(ChildMsg)) .map(move |_| State::Ready(self)); Box::new(future) } Some(RootMsg::FromChild(m)) => { println!("Received message from child: {:?}", m); Box::new(future::ok(State::Done)) } None => { Box::new(future::ok(State::Done)) } } } } impl Actor for Child { type Result = Box, Error = Error> + Send>; fn process(self, _ctx: &mut Context, _msg: Option) -> Self::Result { Box::new(self.parent.send(Hello).map(|_| State::Done)) } } #[test] fn parent_child() -> Result<(), Error> { let pool = ThreadPool::new(); let exec = Scheduler::new(pool.sender().clone()); let mut root = exec.spawn(Root)?; root.send_now(RootMsg::Start)?; pool.shutdown_on_idle().wait().unwrap(); Ok(()) }