From 45d873907f2004ed2da03ea61c5905e30e739bd8 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Fri, 13 Jun 2025 17:11:29 -0700 Subject: [PATCH] bugfixes, better handling of server url changes --- Cargo.lock | 7 +++++++ kordophone/Cargo.toml | 1 + kordophone/src/api/http_client.rs | 3 ++- kordophoned/src/daemon/mod.rs | 25 ++++++++++++++++++++++- kordophoned/src/daemon/update_monitor.rs | 26 ++++++++++++++++++++++-- 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12d628e..ddbe939 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1021,6 +1021,7 @@ dependencies = [ "tokio-tungstenite", "tokio-util", "tungstenite", + "urlencoding", "uuid", ] @@ -2079,6 +2080,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/kordophone/Cargo.toml b/kordophone/Cargo.toml index 24e074c..81d060a 100644 --- a/kordophone/Cargo.toml +++ b/kordophone/Cargo.toml @@ -24,4 +24,5 @@ tokio = { version = "1.37.0", features = ["full"] } tokio-tungstenite = "0.26.2" tokio-util = { version = "0.7.15", features = ["futures-util"] } tungstenite = "0.26.2" +urlencoding = "2.1.3" uuid = { version = "1.6.1", features = ["v4", "fast-rng", "macro-diagnostics"] } diff --git a/kordophone/src/api/http_client.rs b/kordophone/src/api/http_client.rs index 0f379f2..a7be3f7 100644 --- a/kordophone/src/api/http_client.rs +++ b/kordophone/src/api/http_client.rs @@ -346,7 +346,8 @@ impl APIInterface for HTTPAPIClient { .await .map_err(|e| Error::ClientError(e.to_string()))?; - let endpoint = format!("uploadAttachment?filename={}", filename); + let encoded_filename = urlencoding::encode(filename); + let endpoint = format!("uploadAttachment?filename={}", encoded_filename); let mut bytes_opt = Some(bytes); let response: UploadAttachmentResponse = self diff --git a/kordophoned/src/daemon/mod.rs b/kordophoned/src/daemon/mod.rs index b673f9b..0a78113 100644 --- a/kordophoned/src/daemon/mod.rs +++ b/kordophoned/src/daemon/mod.rs @@ -32,7 +32,7 @@ use kordophone::model::outgoing_message::OutgoingMessage; use kordophone::model::ConversationID; mod update_monitor; -use update_monitor::UpdateMonitor; +use update_monitor::{UpdateMonitor, UpdateMonitorCommand}; mod auth_store; use auth_store::DatabaseAuthenticationStore; @@ -80,6 +80,7 @@ pub struct Daemon { outgoing_messages: HashMap>, attachment_store_sink: Option>, + update_monitor_command_tx: Option>, version: String, database: Arc>, @@ -120,6 +121,7 @@ impl Daemon { post_office_source: Some(post_office_source), outgoing_messages: HashMap::new(), attachment_store_sink: None, + update_monitor_command_tx: None, runtime, }) } @@ -131,6 +133,7 @@ impl Daemon { // Update monitor let mut update_monitor = UpdateMonitor::new(self.database.clone(), self.event_sender.clone()); + self.update_monitor_command_tx = Some(update_monitor.take_command_channel()); tokio::spawn(async move { update_monitor.run().await; // should run indefinitely }); @@ -248,10 +251,30 @@ impl Daemon { } Event::UpdateSettings(settings, reply) => { + let previous_server_url = self.get_settings().await.unwrap_or_default().server_url; + self.update_settings(&settings).await.unwrap_or_else(|e| { log::error!(target: target::SETTINGS, "Failed to update settings: {}", e); }); + if previous_server_url != settings.server_url { + // If the server url has changed, we'll need to do a full re-sync. + self.delete_all_conversations().await.unwrap_or_else(|e| { + log::error!(target: target::SYNC, "Failed to delete all conversations: {}", e); + }); + + // Do a sync-list to get the new conversations. + self.spawn_conversation_list_sync(); + + // Also restart the update monitor. + self.update_monitor_command_tx + .as_ref() + .unwrap() + .send(UpdateMonitorCommand::Restart) + .await + .unwrap(); + } + reply.send(()).unwrap(); } diff --git a/kordophoned/src/daemon/update_monitor.rs b/kordophoned/src/daemon/update_monitor.rs index 39ee875..7085dcc 100644 --- a/kordophoned/src/daemon/update_monitor.rs +++ b/kordophoned/src/daemon/update_monitor.rs @@ -15,10 +15,16 @@ use kordophone_db::database::DatabaseAccess; use std::collections::HashMap; use std::sync::Arc; use std::time::{Duration, Instant}; -use tokio::sync::mpsc::Sender; +use tokio::sync::mpsc::{Receiver, Sender}; use tokio::sync::Mutex; +pub enum UpdateMonitorCommand { + Restart, +} + pub struct UpdateMonitor { + command_tx: Option>, + command_rx: Receiver, database: Arc>, event_sender: Sender, last_sync_times: HashMap, @@ -28,16 +34,23 @@ pub struct UpdateMonitor { impl UpdateMonitor { pub fn new(database: Arc>, event_sender: Sender) -> Self { + let (command_tx, command_rx) = tokio::sync::mpsc::channel(1); Self { database, event_sender, last_sync_times: HashMap::new(), update_seq: None, first_connection: false, // optimistic assumption that we're not reconnecting the first time. + command_tx: Some(command_tx), + command_rx, } } - pub async fn send_event( + pub fn take_command_channel(&mut self) -> Sender { + self.command_tx.take().unwrap() + } + + async fn send_event( &self, make_event: impl FnOnce(Reply) -> Event, ) -> DaemonResult { @@ -201,6 +214,15 @@ impl UpdateMonitor { } } } + + Some(command) = self.command_rx.recv() => { + match command { + UpdateMonitorCommand::Restart => { + log::info!(target: target::UPDATES, "Restarting update monitor"); + break; + } + } + } } }