use iroh_gossip::api::GossipSender as IrohGossipSender;
use ractor::thread_local::ThreadLocalActor;
use ractor::{ActorProcessingErr, ActorRef};
use tokio::sync::oneshot;
pub enum ToGossipSender {
WaitUntilJoined(oneshot::Receiver<()>),
Broadcast(Vec<u8>),
}
pub struct GossipSenderState {
sender: Option<IrohGossipSender>,
}
#[derive(Default)]
pub struct GossipSender;
impl ThreadLocalActor for GossipSender {
type State = GossipSenderState;
type Msg = ToGossipSender;
type Arguments = (IrohGossipSender, oneshot::Receiver<()>);
async fn pre_start(
&self,
myself: ActorRef<Self::Msg>,
args: Self::Arguments,
) -> Result<Self::State, ActorProcessingErr> {
let (sender, joined) = args;
let _ = myself.cast(ToGossipSender::WaitUntilJoined(joined));
Ok(GossipSenderState {
sender: Some(sender),
})
}
async fn post_stop(
&self,
_myself: ActorRef<Self::Msg>,
state: &mut Self::State,
) -> Result<(), ActorProcessingErr> {
drop(state.sender.take());
Ok(())
}
async fn handle(
&self,
_myself: ActorRef<Self::Msg>,
message: Self::Msg,
state: &mut Self::State,
) -> Result<(), ActorProcessingErr> {
match message {
ToGossipSender::WaitUntilJoined(joined) => {
let _ = joined.await;
}
ToGossipSender::Broadcast(bytes) => {
if let Some(sender) = &mut state.sender {
sender.broadcast(bytes.into()).await?;
}
}
}
Ok(())
}
}