summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-12-21 11:17:34 +0100
committerMatthias Beyer <mail@beyermatthias.de>2021-12-21 11:17:35 +0100
commita52e91767eb2cbbac96e3e6d9f14d5034ef14912 (patch)
tree417e089b18aca8b08841c36e0e06a513c741fb82
parent83d37b86ba79ebf48484d332f865834492c33e49 (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.rs3
-rw-r--r--gui/src/app/mod.rs36
-rw-r--r--gui/src/gossip.rs5
-rw-r--r--lib/src/gossip/handler.rs8
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;