diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-12-21 11:17:34 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-12-21 11:17:35 +0100 |
commit | a52e91767eb2cbbac96e3e6d9f14d5034ef14912 (patch) | |
tree | 417e089b18aca8b08841c36e0e06a513c741fb82 | |
parent | 83d37b86ba79ebf48484d332f865834492c33e49 (diff) |
Wrap Profile in RwLock
We need mutable access to the profile if we want to write to it, so this
commit changes the Profile to wrapped in a tokio::sync::RwLock
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | gui/src/app/message.rs | 3 | ||||
-rw-r--r-- | gui/src/app/mod.rs | 36 | ||||
-rw-r--r-- | gui/src/gossip.rs | 5 | ||||
-rw-r--r-- | lib/src/gossip/handler.rs | 8 |
4 files changed, 30 insertions, 22 deletions
diff --git a/gui/src/app/message.rs b/gui/src/app/message.rs index dcb7477..68c95d5 100644 --- a/gui/src/app/message.rs +++ b/gui/src/app/message.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use cid::Cid; +use tokio::sync::RwLock; use distrox_lib::gossip::GossipMessage; use distrox_lib::profile::Profile; @@ -10,7 +11,7 @@ use crate::gossip::GossipRecipe; #[derive(Clone, Debug)] pub enum Message { - Loaded(Arc<Profile>), + Loaded(Arc<RwLock<Profile>>), FailedToLoad(String), ToggleLog, diff --git a/gui/src/app/mod.rs b/gui/src/app/mod.rs index 68c56dc..1580353 100644 --- a/gui/src/app/mod.rs +++ b/gui/src/app/mod.rs @@ -1,5 +1,4 @@ use std::sync::Arc; -use std::sync::RwLock as StdRwLock; use anyhow::Result; use iced::Application; @@ -12,6 +11,7 @@ use iced::TextInput; use iced::scrollable; use iced::text_input; use distrox_lib::profile::Profile; +use tokio::sync::RwLock; use crate::timeline::Timeline; use crate::timeline::PostLoadingRecipe; @@ -24,11 +24,11 @@ use crate::gossip::GossipRecipe; #[derive(Debug)] enum Distrox { Loading { - gossip_subscription_recv: StdRwLock<tokio::sync::oneshot::Receiver<GossipRecipe>>, + gossip_subscription_recv: RwLock<tokio::sync::oneshot::Receiver<GossipRecipe>>, }, Loaded { - profile: Arc<Profile>, - gossip_subscription_recv: StdRwLock<tokio::sync::oneshot::Receiver<GossipRecipe>>, + profile: Arc<RwLock<Profile>>, + gossip_subscription_recv: RwLock<tokio::sync::oneshot::Receiver<GossipRecipe>>, scroll: scrollable::State, input: text_input::State, @@ -50,16 +50,19 @@ impl Application for Distrox { let (gossip_subscription_sender, gossip_subscription_recv) = tokio::sync::oneshot::channel(); ( Distrox::Loading { - gossip_subscription_recv: StdRwLock::new(gossip_subscription_recv), + gossip_subscription_recv: RwLock::new(gossip_subscription_recv), }, iced::Command::perform(async move { let profile = match Profile::load(&name).await { Err(e) => return Message::FailedToLoad(e.to_string()), - Ok(instance) => Arc::new(instance), + Ok(instance) => Arc::new(RwLock::new(instance)), }; - if let Err(e) = profile.client() + if let Err(e) = profile + .read() + .await + .client() .pubsub_subscribe("distrox".to_string()) .await .map_err(anyhow::Error::from) @@ -91,7 +94,7 @@ impl Application for Distrox { profile, // Don't even try to think what hoops I am jumping through here... - gossip_subscription_recv: std::mem::replace(gossip_subscription_recv, StdRwLock::new(tokio::sync::oneshot::channel().1)), + gossip_subscription_recv: std::mem::replace(gossip_subscription_recv, RwLock::new(tokio::sync::oneshot::channel().1)), scroll: scrollable::State::default(), input: text_input::State::default(), input_value: String::default(), @@ -181,7 +184,7 @@ impl Application for Distrox { Message::PublishGossipAboutMe => { let profile = profile.clone(); iced::Command::perform(async move { - if let Err(e) = profile.gossip_own_state("distrox".to_string()).await { + if let Err(e) = profile.read().await.gossip_own_state("distrox".to_string()).await { Message::GossippingFailed(e.to_string()) } else { Message::OwnStateGossipped @@ -293,9 +296,12 @@ impl Application for Distrox { fn subscription(&self) -> iced::Subscription<Self::Message> { let post_loading_subs = match self { Distrox::Loaded { profile, .. } => { - let head = profile.head(); + let profile = match profile.try_read() { + Err(_) => return iced::Subscription::none(), + Ok(p) => p, + }; - match head { + match profile.head() { None => iced::Subscription::none(), Some(head) => { iced::Subscription::from_recipe({ @@ -326,11 +332,11 @@ impl Application for Distrox { let gossip_sub = match self { Distrox::Loaded { gossip_subscription_recv, .. } => { - match gossip_subscription_recv.write().ok() { - Some(mut sub) => sub.try_recv() - .ok() // Either empty or closed, ignore both + match gossip_subscription_recv.try_write() { + Err(_) => None, + Ok(mut sub) => sub.try_recv() + .ok() .map(|sub| iced::Subscription::from_recipe(sub)), - None => None } }, _ => None, diff --git a/gui/src/gossip.rs b/gui/src/gossip.rs index ac6bab0..c88c29c 100644 --- a/gui/src/gossip.rs +++ b/gui/src/gossip.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use futures::StreamExt; +use tokio::sync::RwLock; use distrox_lib::profile::Profile; use distrox_lib::client::Client; @@ -9,12 +10,12 @@ use crate::app::Message; #[derive(Clone, Debug)] pub struct GossipRecipe { - profile: Arc<Profile>, + profile: Arc<RwLock<Profile>>, subscription: Arc<ipfs::SubscriptionStream>, } impl GossipRecipe { - pub fn new(profile: Arc<Profile>, subscription: ipfs::SubscriptionStream) -> Self { + pub fn new(profile: Arc<RwLock<Profile>>, subscription: ipfs::SubscriptionStream) -> Self { Self { profile, subscription: Arc::new(subscription) } } } diff --git a/lib/src/gossip/handler.rs b/lib/src/gossip/handler.rs index 7c9ffa6..e524da8 100644 --- a/lib/src/gossip/handler.rs +++ b/lib/src/gossip/handler.rs @@ -18,14 +18,14 @@ use crate::gossip::GossipMessage; pub struct GossipHandler<Strategy = LogStrategy> where Strategy: GossipHandlingStrategy + Sync + Send { - profile: Arc<Profile>, + profile: Arc<RwLock<Profile>>, strategy: std::marker::PhantomData<Strategy>, } impl<Strat> GossipHandler<Strat> where Strat: GossipHandlingStrategy + Sync + Send { - pub fn new(profile: Arc<Profile>) -> Self { + pub fn new(profile: Arc<RwLock<Profile>>) -> Self { Self { profile, strategy: std::marker::PhantomData, @@ -48,14 +48,14 @@ impl<Strat> GossipHandler<Strat> #[async_trait::async_trait] pub trait GossipHandlingStrategy: Sync + Send { - async fn handle_gossip_message(profile: Arc<Profile>, source: &ipfs::PeerId, msg: &GossipMessage) -> Result<()>; + async fn handle_gossip_message(profile: Arc<RwLock<Profile>>, source: &ipfs::PeerId, msg: &GossipMessage) -> Result<()>; } pub struct LogStrategy; #[async_trait::async_trait] impl GossipHandlingStrategy for LogStrategy { - async fn handle_gossip_message(_profile: Arc<Profile>, source: &ipfs::PeerId, msg: &GossipMessage) -> Result<()> { + async fn handle_gossip_message(_profile: Arc<RwLock<Profile>>, source: &ipfs::PeerId, msg: &GossipMessage) -> Result<()> { use std::convert::TryFrom; use std::ops::Deref; |