fix crash by fusing oneshot
This commit is contained in:
parent
7dc1b1f35d
commit
eda4bd92ff
|
@ -1 +1,2 @@
|
|||
luz.db
|
||||
.sqlx/
|
||||
|
|
|
@ -8,6 +8,7 @@ use chat::{Body, Chat, Message};
|
|||
use connection::{write::WriteMessage, SupervisorSender};
|
||||
use db::Db;
|
||||
use error::{ConnectionError, Reason, RosterError, StatusError};
|
||||
use futures::{future::Fuse, FutureExt};
|
||||
use jabber::JID;
|
||||
use presence::{Offline, Online, Presence};
|
||||
use roster::{Contact, ContactUpdate};
|
||||
|
@ -47,7 +48,7 @@ pub struct Luz {
|
|||
db: Db,
|
||||
sender: mpsc::Sender<UpdateMessage>,
|
||||
/// if connection was shut down due to e.g. server shutdown, supervisor must be able to mark client as disconnected
|
||||
connection_supervisor_shutdown: oneshot::Receiver<()>,
|
||||
connection_supervisor_shutdown: Fuse<oneshot::Receiver<()>>,
|
||||
// TODO: will need to have an auto reconnect state as well (e.g. in case server shut down, to try and reconnect later)
|
||||
// TODO: will grow forever at this point, maybe not required as tasks will naturally shut down anyway?
|
||||
tasks: JoinSet<()>,
|
||||
|
@ -60,7 +61,7 @@ impl Luz {
|
|||
jid: Arc<Mutex<JID>>,
|
||||
password: String,
|
||||
connected: Arc<Mutex<Option<(WriteHandle, SupervisorHandle)>>>,
|
||||
connection_supervisor_shutdown: oneshot::Receiver<()>,
|
||||
connection_supervisor_shutdown: Fuse<oneshot::Receiver<()>>,
|
||||
db: SqlitePool,
|
||||
sender: mpsc::Sender<UpdateMessage>,
|
||||
) -> Self {
|
||||
|
@ -82,9 +83,8 @@ impl Luz {
|
|||
loop {
|
||||
let msg = tokio::select! {
|
||||
// this is okay, as when created the supervisor (and connection) doesn't exist, but a bit messy
|
||||
// THIS IS NOT OKAY LOLLLL
|
||||
// THIS IS NOT OKAY LOLLLL - apparently fusing is the best option???
|
||||
_ = &mut self.connection_supervisor_shutdown => {
|
||||
info!("got this");
|
||||
*self.connected.lock().await = None;
|
||||
continue;
|
||||
}
|
||||
|
@ -130,6 +130,7 @@ impl Luz {
|
|||
self.password.clone(),
|
||||
self.pending_iqs.clone(),
|
||||
);
|
||||
let shutdown_recv = shutdown_recv.fuse();
|
||||
self.connection_supervisor_shutdown = shutdown_recv;
|
||||
// TODO: get roster and send initial presence
|
||||
let (send, recv) = oneshot::channel();
|
||||
|
@ -237,7 +238,7 @@ impl Luz {
|
|||
}
|
||||
};
|
||||
}
|
||||
CommandMessage::Disconnect(_offline) => {
|
||||
CommandMessage::Disconnect(offline) => {
|
||||
match self.connected.lock().await.as_mut() {
|
||||
None => {
|
||||
let _ = self
|
||||
|
@ -247,15 +248,19 @@ impl Luz {
|
|||
}
|
||||
mut c => {
|
||||
// TODO: send unavailable presence
|
||||
if let Some((_write_handle, supervisor_handle)) = c.take() {
|
||||
if let Some((write_handle, supervisor_handle)) = c.take() {
|
||||
let offline_presence: stanza::client::presence::Presence =
|
||||
offline.clone().into();
|
||||
let stanza = Stanza::Presence(offline_presence);
|
||||
// TODO: timeout and error check
|
||||
write_handle.write(stanza).await;
|
||||
let _ = supervisor_handle.send(SupervisorCommand::Disconnect).await;
|
||||
c = None;
|
||||
let _ = self.sender.send(UpdateMessage::Offline(offline)).await;
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
}
|
||||
}
|
||||
info!("lock released")
|
||||
}
|
||||
_ => {
|
||||
match self.connected.lock().await.as_ref() {
|
||||
|
@ -1004,6 +1009,7 @@ impl LuzHandle {
|
|||
let (update_sender, update_receiver) = mpsc::channel(20);
|
||||
// might be bad, first supervisor shutdown notification oneshot is never used (disgusting)
|
||||
let (sup_send, sup_recv) = oneshot::channel();
|
||||
let mut sup_recv = sup_recv.fuse();
|
||||
|
||||
let actor = Luz::new(
|
||||
command_sender.clone(),
|
||||
|
|
|
@ -12,9 +12,13 @@ use tracing::info;
|
|||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
let db = SqlitePool::connect("./luz.db").await.unwrap();
|
||||
let (luz, mut recv) =
|
||||
LuzHandle::new("test@blos.sm".try_into().unwrap(), "slayed".to_string(), db);
|
||||
let (luz, mut recv) = LuzHandle::new(
|
||||
"test@blos.sm".try_into().unwrap(),
|
||||
"slayed".to_string(),
|
||||
"./luz.db",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
while let Some(msg) = recv.recv().await {
|
||||
|
|
|
@ -91,3 +91,22 @@ impl From<Online> for stanza::client::presence::Presence {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Offline> for stanza::client::presence::Presence {
|
||||
fn from(value: Offline) -> Self {
|
||||
Self {
|
||||
from: None,
|
||||
id: None,
|
||||
to: None,
|
||||
r#type: Some(stanza::client::presence::PresenceType::Unavailable),
|
||||
lang: None,
|
||||
show: None,
|
||||
status: value.status.map(|status| stanza::client::presence::Status {
|
||||
lang: None,
|
||||
status: String1024(status),
|
||||
}),
|
||||
priority: None,
|
||||
errors: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue