You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
32 lines
1.0 KiB
32 lines
1.0 KiB
use xtra::prelude::MessageChannel;
|
|
|
|
/// A fan-out actor takes every incoming message and forwards it to a set of other actors.
|
|
pub struct Actor<M: xtra::Message<Result = ()>> {
|
|
receivers: Vec<Box<dyn MessageChannel<M>>>,
|
|
}
|
|
|
|
impl<M: xtra::Message<Result = ()>> Actor<M> {
|
|
pub fn new(receivers: &[&dyn MessageChannel<M>]) -> Self {
|
|
Self {
|
|
receivers: receivers.iter().map(|c| c.clone_channel()).collect(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<M> xtra::Actor for Actor<M> where M: xtra::Message<Result = ()> {}
|
|
|
|
#[async_trait::async_trait]
|
|
impl<M> xtra::Handler<M> for Actor<M>
|
|
where
|
|
M: xtra::Message<Result = ()> + Clone + Sync + 'static,
|
|
{
|
|
async fn handle(&mut self, message: M, _: &mut xtra::Context<Self>) {
|
|
for receiver in &self.receivers {
|
|
if receiver.send(message.clone()).await.is_err() {
|
|
// Should ideally remove from list but that is unnecessarily hard with Rust
|
|
// iterators
|
|
tracing::error!("Actor disconnected, cannot send message");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|