Private
Public Access
1
0

websocket: automatically reconnect if not heard from for a while

This commit is contained in:
2025-05-14 17:39:23 -07:00
parent 4ad9613827
commit 83eb97fd9c
5 changed files with 80 additions and 23 deletions

View File

@@ -9,6 +9,7 @@ use crate::daemon::{
use kordophone::APIInterface;
use kordophone::api::event_socket::EventSocket;
use kordophone::model::event::Event as UpdateEvent;
use kordophone::model::event::EventData as UpdateEventData;
use kordophone_db::database::Database;
use kordophone_db::database::DatabaseAccess;
@@ -23,6 +24,7 @@ pub struct UpdateMonitor {
database: Arc<Mutex<Database>>,
event_sender: Sender<Event>,
last_sync_times: HashMap<String, Instant>,
update_seq: Option<u64>,
}
impl UpdateMonitor {
@@ -31,6 +33,7 @@ impl UpdateMonitor {
database,
event_sender,
last_sync_times: HashMap::new(),
update_seq: None,
}
}
@@ -47,8 +50,10 @@ impl UpdateMonitor {
}
async fn handle_update(&mut self, update: UpdateEvent) {
match update {
UpdateEvent::ConversationChanged(conversation) => {
self.update_seq = Some(update.update_seq);
match update.data {
UpdateEventData::ConversationChanged(conversation) => {
log::info!(target: target::UPDATES, "Conversation changed: {:?}", conversation);
// Check if we've synced this conversation recently (within 5 seconds)
@@ -84,7 +89,7 @@ impl UpdateMonitor {
});
}
UpdateEvent::MessageReceived(conversation, message) => {
UpdateEventData::MessageReceived(conversation, message) => {
log::info!(target: target::UPDATES, "Message received: msgid:{:?}, convid:{:?}", message.guid, conversation.guid);
log::info!(target: target::UPDATES, "Triggering message sync for conversation id: {}", conversation.guid);
self.send_event(|r| Event::SyncConversation(conversation.guid, r)).await
@@ -113,7 +118,7 @@ impl UpdateMonitor {
};
log::debug!(target: target::UPDATES, "Opening event socket");
let socket = match client.open_event_socket().await {
let socket = match client.open_event_socket(self.update_seq).await {
Ok(events) => events,
Err(e) => {
log::warn!("Failed to open event socket: {}", e);
@@ -125,9 +130,40 @@ impl UpdateMonitor {
log::debug!(target: target::UPDATES, "Starting event stream");
let mut event_stream = socket.events().await;
while let Some(Ok(event)) = event_stream.next().await {
self.handle_update(event).await;
// We won't know if the websocket is dead until we try to send a message, so time out waiting for
// a message every 30 seconds.
let mut timeout = tokio::time::interval(Duration::from_secs(30));
timeout.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
// First tick will happen immediately
timeout.tick().await;
loop {
tokio::select! {
Some(result) = event_stream.next() => {
match result {
Ok(event) => {
self.handle_update(event).await;
// Reset the timeout since we got a message
timeout.reset();
}
Err(e) => {
log::error!("Error in event stream: {}", e);
break; // Break inner loop to reconnect
}
}
}
_ = timeout.tick() => {
log::warn!("No messages received for 30 seconds, reconnecting...");
break; // Break inner loop to reconnect
}
}
}
// Add a small delay before reconnecting to avoid tight reconnection loops
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
}