From 9974f69a27dfcf672d2e22d0cd3cdd6ac1d70d93 Mon Sep 17 00:00:00 2001 From: boxdot Date: Fri, 1 Mar 2024 16:47:00 +0100 Subject: [PATCH 1/3] fix: cache contact names When rendering we look up the contact names in signal manager. This is an IO operation and so quite expensive. We cache now the names in memory. --- src/app.rs | 52 ++++++++++++++++++++++++++++++++++++---------------- src/data.rs | 2 +- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/app.rs b/src/app.rs index 754768f..29cff3a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -10,6 +10,7 @@ use crate::signal::{ }; use crate::storage::{MessageId, Storage}; use crate::util::{self, LazyRegex, StatefulList, ATTACHMENT_REGEX, URL_REGEX}; +use std::cell::Cell; use std::io::Cursor; use anyhow::{anyhow, Context as _}; @@ -64,6 +65,8 @@ pub struct App { pub(crate) select_channel: SelectChannel, clipboard: Option, event_tx: mpsc::UnboundedSender, + // It is expensive to hit the signal manager contacts storage, so we cache it + names_cache: Cell>>, } impl App { @@ -119,6 +122,7 @@ impl App { select_channel: Default::default(), clipboard, event_tx, + names_cache: Default::default(), }; Ok((app, event_rx)) } @@ -164,23 +168,39 @@ impl App { pub fn name_by_id(&self, id: Uuid) -> String { if self.user_id == id { // it's me - self.config.user.name.clone() - } else if let Some(contact) = self - .signal_manager - .contact_by_id(id) - .ok() - .flatten() - .filter(|contact| !contact.name.is_empty()) - { - // user is known via our contact list - contact.name - } else if let Some(name) = self.storage.name(id).filter(|name| !name.is_empty()) { - // user should be at least known via their profile or phone number - name.into_owned() - } else { + return self.config.user.name.clone(); + }; + self.name_by_id_cached(id, |id| { + if let Some(name) = self + .signal_manager + .contact_by_id(id) + .ok() + .flatten() + .map(|contact| contact.name) + .filter(|name| !name.trim().is_empty()) + { + return name; + } + if let Some(name) = self.storage.name(id).filter(|name| !name.trim().is_empty()) { + // user should be at least known via their profile or phone number + return name.into_owned(); + } // give up id.to_string() - } + }) + } + + fn name_by_id_cached(&self, id: Uuid, on_miss: impl FnOnce(Uuid) -> String) -> String { + let mut cache = self.names_cache.take().unwrap_or_default(); + let name = if let Some(name) = cache.get(&id).cloned() { + name + } else { + let name = on_miss(id); + cache.insert(id, name.clone()); + name + }; + self.names_cache.replace(Some(cache)); + name } pub fn channel_name<'a>(&self, channel: &'a Channel) -> Cow<'a, str> { @@ -436,7 +456,7 @@ impl App { } pub async fn on_message(&mut self, content: Content) -> anyhow::Result<()> { - // tracing::debug!("incoming: {:#?}", content); + tracing::debug!("incoming: {:#?}", content); #[cfg(feature = "dev")] if self.config.developer.dump_raw_messages { diff --git a/src/data.rs b/src/data.rs index fd38640..c21f2d1 100644 --- a/src/data.rs +++ b/src/data.rs @@ -246,7 +246,7 @@ impl BodyRange { AssociatedValue::MentionUuid(uuid) } proto::body_range::AssociatedValue::Style(style) => AssociatedValue::Style( - proto::body_range::Style::from_i32(style) + proto::body_range::Style::try_from(style) .map(Style::from_proto) .unwrap_or_default(), ), From 25116cd6bb297bd58b51b6870d27a63c08f1958e Mon Sep 17 00:00:00 2001 From: boxdot Date: Fri, 1 Mar 2024 16:50:08 +0100 Subject: [PATCH 2/3] disable logging of content --- src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 29cff3a..c91bfa5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -456,7 +456,7 @@ impl App { } pub async fn on_message(&mut self, content: Content) -> anyhow::Result<()> { - tracing::debug!("incoming: {:#?}", content); + // tracing::debug!("incoming: {:#?}", content); #[cfg(feature = "dev")] if self.config.developer.dump_raw_messages { From 044b1aed31cb2e7eb931df6f35e669aaaf9ad4da Mon Sep 17 00:00:00 2001 From: boxdot Date: Fri, 1 Mar 2024 17:01:15 +0100 Subject: [PATCH 3/3] restore conversion --- src/data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data.rs b/src/data.rs index c21f2d1..fd38640 100644 --- a/src/data.rs +++ b/src/data.rs @@ -246,7 +246,7 @@ impl BodyRange { AssociatedValue::MentionUuid(uuid) } proto::body_range::AssociatedValue::Style(style) => AssociatedValue::Style( - proto::body_range::Style::try_from(style) + proto::body_range::Style::from_i32(style) .map(Style::from_proto) .unwrap_or_default(), ),