minor refactors, add OutgoingMessage
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
use crate::listener::{ListenerEvent, ListenerHandle};
|
||||
use crate::message_repo::Db;
|
||||
use crate::models::{self, Message, NotificationProxy};
|
||||
use crate::models::{self, NotificationProxy, ReceivedMessage};
|
||||
use crate::{Error, ServerEvent, SharedEnv};
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
@ -9,31 +9,58 @@ use tokio::sync::{broadcast, mpsc, oneshot, watch, RwLock};
|
||||
use tokio::task::spawn_local;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
enum SubscriptionCommand {
|
||||
GetModel {
|
||||
resp_tx: oneshot::Sender<models::Subscription>,
|
||||
},
|
||||
UpdateInfo {
|
||||
new_model: models::Subscription,
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
Attach {
|
||||
resp_tx: oneshot::Sender<(Vec<ListenerEvent>, broadcast::Receiver<ListenerEvent>)>,
|
||||
},
|
||||
Publish {
|
||||
msg: String,
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
ClearNotifications {
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
UpdateReadUntil {
|
||||
timestamp: u64,
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubscriptionHandle {
|
||||
sender: mpsc::Sender<SubscriptionRequest>,
|
||||
command_tx: mpsc::Sender<SubscriptionCommand>,
|
||||
listener: ListenerHandle,
|
||||
}
|
||||
|
||||
impl SubscriptionHandle {
|
||||
pub fn new(listener: ListenerHandle, model: models::Subscription, env: &SharedEnv) -> Self {
|
||||
let (sender, receiver) = mpsc::channel(32);
|
||||
let (command_tx, command_rx) = mpsc::channel(32);
|
||||
let broadcast_tx = broadcast::channel(8).0;
|
||||
let actor = SubscriptionActor {
|
||||
listener: listener.clone(),
|
||||
model,
|
||||
receiver,
|
||||
command_rx,
|
||||
env: env.clone(),
|
||||
broadcast_tx: broadcast_tx.clone(),
|
||||
};
|
||||
spawn_local(actor.run());
|
||||
Self { sender, listener }
|
||||
Self {
|
||||
command_tx,
|
||||
listener,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn model(&self) -> models::Subscription {
|
||||
let (resp_tx, resp_rx) = oneshot::channel();
|
||||
self.sender
|
||||
.send(SubscriptionRequest::GetModel { resp_tx })
|
||||
self.command_tx
|
||||
.send(SubscriptionCommand::GetModel { resp_tx })
|
||||
.await
|
||||
.unwrap();
|
||||
resp_rx.await.unwrap()
|
||||
@ -41,8 +68,8 @@ impl SubscriptionHandle {
|
||||
|
||||
pub async fn update_info(&self, new_model: models::Subscription) -> anyhow::Result<()> {
|
||||
let (resp_tx, resp_rx) = oneshot::channel();
|
||||
self.sender
|
||||
.send(SubscriptionRequest::UpdateInfo { new_model, resp_tx })
|
||||
self.command_tx
|
||||
.send(SubscriptionCommand::UpdateInfo { new_model, resp_tx })
|
||||
.await?;
|
||||
resp_rx.await.unwrap()
|
||||
}
|
||||
@ -68,8 +95,8 @@ impl SubscriptionHandle {
|
||||
// The `ListenerHandle` is returned to receive new events.
|
||||
pub async fn attach(&self) -> (Vec<ListenerEvent>, broadcast::Receiver<ListenerEvent>) {
|
||||
let (resp_tx, resp_rx) = oneshot::channel();
|
||||
self.sender
|
||||
.send(SubscriptionRequest::Attach { resp_tx })
|
||||
self.command_tx
|
||||
.send(SubscriptionCommand::Attach { resp_tx })
|
||||
.await
|
||||
.unwrap();
|
||||
resp_rx.await.unwrap()
|
||||
@ -77,8 +104,8 @@ impl SubscriptionHandle {
|
||||
|
||||
pub async fn publish(&self, msg: String) -> anyhow::Result<()> {
|
||||
let (resp_tx, resp_rx) = oneshot::channel();
|
||||
self.sender
|
||||
.send(SubscriptionRequest::Publish { msg, resp_tx })
|
||||
self.command_tx
|
||||
.send(SubscriptionCommand::Publish { msg, resp_tx })
|
||||
.await
|
||||
.unwrap();
|
||||
resp_rx.await.unwrap()
|
||||
@ -86,8 +113,8 @@ impl SubscriptionHandle {
|
||||
|
||||
pub async fn clear_notifications(&self) -> anyhow::Result<()> {
|
||||
let (resp_tx, resp_rx) = oneshot::channel();
|
||||
self.sender
|
||||
.send(SubscriptionRequest::ClearNotifications { resp_tx })
|
||||
self.command_tx
|
||||
.send(SubscriptionCommand::ClearNotifications { resp_tx })
|
||||
.await
|
||||
.unwrap();
|
||||
resp_rx.await.unwrap()
|
||||
@ -95,8 +122,8 @@ impl SubscriptionHandle {
|
||||
|
||||
pub async fn update_read_until(&self, timestamp: u64) -> anyhow::Result<()> {
|
||||
let (resp_tx, resp_rx) = oneshot::channel();
|
||||
self.sender
|
||||
.send(SubscriptionRequest::UpdateReadUntil { timestamp, resp_tx })
|
||||
self.command_tx
|
||||
.send(SubscriptionCommand::UpdateReadUntil { timestamp, resp_tx })
|
||||
.await
|
||||
.unwrap();
|
||||
resp_rx.await.unwrap()
|
||||
@ -106,7 +133,7 @@ impl SubscriptionHandle {
|
||||
struct SubscriptionActor {
|
||||
listener: ListenerHandle,
|
||||
model: models::Subscription,
|
||||
receiver: mpsc::Receiver<SubscriptionRequest>,
|
||||
command_rx: mpsc::Receiver<SubscriptionCommand>,
|
||||
env: SharedEnv,
|
||||
broadcast_tx: broadcast::Sender<ListenerEvent>,
|
||||
}
|
||||
@ -123,12 +150,12 @@ impl SubscriptionActor {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(request) = self.receiver.recv() => {
|
||||
match request {
|
||||
SubscriptionRequest::GetModel { resp_tx } => {
|
||||
Some(command) = self.command_rx.recv() => {
|
||||
match command {
|
||||
SubscriptionCommand::GetModel { resp_tx } => {
|
||||
let _ = resp_tx.send(self.model.clone());
|
||||
}
|
||||
SubscriptionRequest::UpdateInfo {
|
||||
SubscriptionCommand::UpdateInfo {
|
||||
mut new_model,
|
||||
resp_tx,
|
||||
} => {
|
||||
@ -140,10 +167,10 @@ impl SubscriptionActor {
|
||||
}
|
||||
resp_tx.send(res.map_err(|e| e.into()));
|
||||
}
|
||||
SubscriptionRequest::Publish {msg, resp_tx} => {
|
||||
SubscriptionCommand::Publish {msg, resp_tx} => {
|
||||
let _ = resp_tx.send(self.publish(msg).await);
|
||||
}
|
||||
SubscriptionRequest::Attach { resp_tx } => {
|
||||
SubscriptionCommand::Attach { resp_tx } => {
|
||||
let messages = self
|
||||
.env
|
||||
.db
|
||||
@ -163,13 +190,13 @@ impl SubscriptionActor {
|
||||
})
|
||||
.map(ListenerEvent::Message)
|
||||
.collect();
|
||||
previous_events.push(ListenerEvent::ConnectionStateChanged(self.listener.request_state().await));
|
||||
previous_events.push(ListenerEvent::ConnectionStateChanged(self.listener.state().await));
|
||||
let _ = resp_tx.send((previous_events, self.broadcast_tx.subscribe()));
|
||||
}
|
||||
SubscriptionRequest::ClearNotifications {resp_tx} => {
|
||||
SubscriptionCommand::ClearNotifications {resp_tx} => {
|
||||
let _ = resp_tx.send(self.env.db.delete_messages(&self.model.server, &self.model.topic).map_err(|e| anyhow::anyhow!(e)));
|
||||
}
|
||||
SubscriptionRequest::UpdateReadUntil { timestamp, resp_tx } => {
|
||||
SubscriptionCommand::UpdateReadUntil { timestamp, resp_tx } => {
|
||||
let res = self.env.db.update_read_until(&self.model.server, &self.model.topic, timestamp);
|
||||
let _ = resp_tx.send(res.map_err(|e| anyhow::anyhow!(e)));
|
||||
}
|
||||
@ -192,7 +219,7 @@ impl SubscriptionActor {
|
||||
res.error_for_status()?;
|
||||
Ok(())
|
||||
}
|
||||
fn handle_msg_event(&mut self, msg: Message) {
|
||||
fn handle_msg_event(&mut self, msg: ReceivedMessage) {
|
||||
// Store in database
|
||||
let already_stored: bool = {
|
||||
let json_ev = &serde_json::to_string(&msg).unwrap();
|
||||
@ -231,27 +258,3 @@ impl SubscriptionActor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SubscriptionRequest {
|
||||
GetModel {
|
||||
resp_tx: oneshot::Sender<models::Subscription>,
|
||||
},
|
||||
UpdateInfo {
|
||||
new_model: models::Subscription,
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
Attach {
|
||||
resp_tx: oneshot::Sender<(Vec<ListenerEvent>, broadcast::Receiver<ListenerEvent>)>,
|
||||
},
|
||||
Publish {
|
||||
msg: String,
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
ClearNotifications {
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
UpdateReadUntil {
|
||||
timestamp: u64,
|
||||
resp_tx: oneshot::Sender<anyhow::Result<()>>,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user