diff --git a/Cargo.lock b/Cargo.lock index f177a47e..eaeba4b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1697,6 +1697,7 @@ dependencies = [ "lazy_static", "linkify", "nostr-types", + "parking_lot", "rand 0.8.5", "reqwest", "rusqlite", diff --git a/Cargo.toml b/Cargo.toml index 7e6ce072..5d17cc77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ image = "0.24" lazy_static = "1.4" linkify = "0.9" nostr-types = { git = "https://github.com/mikedilger/nostr-types" } +parking_lot = "0.12" rand = "0.8" reqwest = { version = "0.11", features = ["json"] } rusqlite = { version = "0.28", features = ["bundled", "chrono", "serde_json"] } diff --git a/src/feed.rs b/src/feed.rs index 4ca5d693..f9fdfefc 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -1,55 +1,56 @@ use crate::globals::GLOBALS; use nostr_types::{Event, EventKind, Id}; use std::time::{Duration, Instant}; +use parking_lot::RwLock; pub struct Feed { - feed: Vec, + feed: RwLock>, // We only recompute the feed at specified intervals - interval_ms: u32, - last_computed: Instant, + interval_ms: RwLock, + last_computed: RwLock, // We track these to update subscriptions on them - my_event_ids: Vec, - followed_event_ids: Vec, + my_event_ids: RwLock>, + followed_event_ids: RwLock>, } impl Feed { pub fn new() -> Feed { Feed { - feed: Vec::new(), - interval_ms: 1000, // Every second, until we load from settings - last_computed: Instant::now(), - my_event_ids: Vec::new(), - followed_event_ids: Vec::new(), + feed: RwLock::new(Vec::new()), + interval_ms: RwLock::new(1000), // Every second, until we load from settings + last_computed: RwLock::new(Instant::now()), + my_event_ids: RwLock::new(Vec::new()), + followed_event_ids: RwLock::new(Vec::new()), } } - pub fn get(&mut self) -> Vec { + pub fn get(&self) -> Vec { let now = Instant::now(); - if self.last_computed + Duration::from_millis(self.interval_ms as u64) < now { + if *self.last_computed.read() + Duration::from_millis(*self.interval_ms.read() as u64) < now { self.recompute(); - self.last_computed = now; + *self.last_computed.write() = now; } - self.feed.clone() + self.feed.read().clone() } #[allow(dead_code)] pub fn get_my_event_ids(&self) -> Vec { // we assume the main get() happens fast enough to recompute for us. - self.my_event_ids.clone() + self.my_event_ids.read().clone() } #[allow(dead_code)] pub fn get_followed_event_ids(&self) -> Vec { // we assume the main get() happens fast enough to recompute for us. - self.followed_event_ids.clone() + self.followed_event_ids.read().clone() } - fn recompute(&mut self) { + fn recompute(&self) { let settings = GLOBALS.settings.blocking_read().clone(); - self.interval_ms = settings.feed_recompute_interval_ms; + *self.interval_ms.write() = settings.feed_recompute_interval_ms; let events: Vec = GLOBALS .events @@ -62,17 +63,17 @@ impl Feed { // My event ids if let Some(pubkey) = GLOBALS.signer.blocking_read().public_key() { - self.my_event_ids = events + *self.my_event_ids.write() = events .iter() .filter_map(|e| if e.pubkey == pubkey { Some(e.id) } else { None }) .collect(); } else { - self.my_event_ids = vec![]; + *self.my_event_ids.write() = vec![]; } // Followed event ids let followed_pubkeys = GLOBALS.people.blocking_read().get_followed_pubkeys(); - self.followed_event_ids = events + *self.followed_event_ids.write() = events .iter() .filter_map(|e| { if followed_pubkeys.contains(&e.pubkey.into()) { @@ -107,6 +108,6 @@ impl Feed { events.sort_unstable_by(|a, b| b.created_at.cmp(&a.created_at)); - self.feed = events.iter().map(|e| e.id).collect(); + *self.feed.write() = events.iter().map(|e| e.id).collect(); } } diff --git a/src/globals.rs b/src/globals.rs index c071ceb1..b3f6ab10 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -71,7 +71,7 @@ pub struct Globals { pub event_is_new: RwLock>, /// Feed - pub feed: Mutex, + pub feed: Feed, /// Fetcher pub fetcher: Fetcher, @@ -106,7 +106,7 @@ lazy_static! { signer: RwLock::new(Signer::default()), dismissed: RwLock::new(Vec::new()), event_is_new: RwLock::new(Vec::new()), - feed: Mutex::new(Feed::new()), + feed: Feed::new(), fetcher: Fetcher::new(), failed_avatars: RwLock::new(HashSet::new()), } diff --git a/src/ui/feed/mod.rs b/src/ui/feed/mod.rs index e901dac5..ba533049 100644 --- a/src/ui/feed/mod.rs +++ b/src/ui/feed/mod.rs @@ -36,7 +36,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram ui.separator(); if app.page == Page::FeedGeneral { - let feed = GLOBALS.feed.blocking_lock().get(); + let feed = GLOBALS.feed.get(); Globals::trim_desired_events_sync(); let desired_count: isize = match GLOBALS.desired_events.try_read() {