From 28c5930b6d8586e75d517814089ec8afbb0ae776 Mon Sep 17 00:00:00 2001 From: frederik Date: Thu, 29 Aug 2024 15:35:12 +0200 Subject: [PATCH] dont use mutex anymore --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/api.rs | 40 +++++++++++++++++++--------------------- src/crate_lookup.rs | 29 ++++++++++++++++------------- src/lsp.rs | 14 +++++++------- 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c27fe4..e8bb4f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cargotom" -version = "0.5.0" +version = "0.5.1" dependencies = [ "clap", "git2", diff --git a/Cargo.toml b/Cargo.toml index 1a271d7..c4ef104 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargotom" -version = "0.5.0" +version = "0.5.1" edition = "2021" [dependencies] diff --git a/src/api.rs b/src/api.rs index aa6de4d..d086763 100644 --- a/src/api.rs +++ b/src/api.rs @@ -16,7 +16,7 @@ pub enum InfoCacheEntry { impl CratesIoStorage { pub async fn search_online(&self, query: &str) -> Result, reqwest::Error> { let notify = Arc::new(Notify::new()); - let cache_lock = self.search_cache.lock().await; + let cache_lock = self.search_cache.read().await; if let Some(entry) = cache_lock.get(query) { match entry { @@ -25,7 +25,7 @@ impl CratesIoStorage { drop(cache_lock); cloned_notify.notified().await; - let cache_lock = self.search_cache.lock().await; + let cache_lock = self.search_cache.read().await; if let Some(SearchCacheEntry::Ready(result)) = cache_lock.get(query) { return Ok(result.clone()); } @@ -36,10 +36,10 @@ impl CratesIoStorage { } } - { - let mut cache_lock = self.search_cache.lock().await; - cache_lock.insert(query.to_string(), SearchCacheEntry::Pending(notify.clone())); - } + // { + // let mut cache_lock = self.search_cache.lock().await; + // cache_lock.insert(query.to_string(), SearchCacheEntry::Pending(notify.clone())); + // } let url = format!( "https://crates.io/api/v1/crates?page=1&per_page={}&q={}&sort=relevance", @@ -55,7 +55,7 @@ impl CratesIoStorage { match res { Ok(search_response) => { - let mut cache_lock = self.search_cache.lock().await; + let mut cache_lock = self.search_cache.write().await; cache_lock.insert( query.to_string(), SearchCacheEntry::Ready(search_response.crates.clone()), @@ -64,7 +64,7 @@ impl CratesIoStorage { Ok(search_response.crates) } Err(e) => { - let mut cache_lock = self.search_cache.lock().await; + let mut cache_lock = self.search_cache.write().await; cache_lock.remove(query); notify.notify_waiters(); Err(e) @@ -76,17 +76,17 @@ impl CratesIoStorage { &self, name: &str, ) -> Result, reqwest::Error> { - let notify = Arc::new(Notify::new()); - let cache_lock = self.versions_cache.lock().await; + //let notify = Arc::new(Notify::new()); + let cache_lock = self.versions_cache.read().await; if let Some(entry) = cache_lock.get(name) { match entry { InfoCacheEntry::Pending(existing_notify) => { - let cloned_notify = existing_notify.clone(); + let notify = existing_notify.clone(); drop(cache_lock); - cloned_notify.notified().await; + notify.notified().await; - let cache_lock = self.versions_cache.lock().await; + let cache_lock = self.versions_cache.read().await; if let Some(InfoCacheEntry::Ready(result)) = cache_lock.get(name) { return Ok(result.clone()); } @@ -96,11 +96,10 @@ impl CratesIoStorage { } } } + //let mut cache_lock = self.versions_cache.lock().await; - { - let mut cache_lock = self.versions_cache.lock().await; - cache_lock.insert(name.to_string(), InfoCacheEntry::Pending(notify.clone())); - } + //cache_lock.insert(name.to_string(), InfoCacheEntry::Pending(notify.clone())); + //drop(cache_lock); let url = format!("https://crates.io/api/v1/crates/{}/versions", name); @@ -110,18 +109,17 @@ impl CratesIoStorage { Err(e) => Err(e), }; + let mut cache_lock = self.versions_cache.write().await; match res { Ok(search_response) => { - let mut cache_lock = self.versions_cache.lock().await; let versions = search_response.versions(); cache_lock.insert(name.to_string(), InfoCacheEntry::Ready(versions.clone())); - notify.notify_waiters(); + //notify.notify_waiters(); Ok(versions) } Err(e) => { - let mut cache_lock = self.search_cache.lock().await; cache_lock.remove(name); - notify.notify_waiters(); + //notify.notify_waiters(); Err(e) } } diff --git a/src/crate_lookup.rs b/src/crate_lookup.rs index 1cf4700..6124caa 100644 --- a/src/crate_lookup.rs +++ b/src/crate_lookup.rs @@ -8,7 +8,10 @@ type OfflineCratesData = Option)>>>; use reqwest::Client; use taplo::HashMap; -use tokio::{sync::Mutex, time::sleep}; +use tokio::{ + sync::{Mutex, RwLock}, + time::sleep, +}; use trie_rs::map::{Trie, TrieBuilder}; use crate::{ @@ -16,7 +19,7 @@ use crate::{ git::updated_local_git, }; -pub type Shared = Arc>; +pub type Shared = Arc>; #[derive(Clone)] pub struct CratesIoStorage { pub search_cache: Shared>, @@ -83,7 +86,7 @@ fn read_data(path: &Path) -> OfflineCratesData { } pub fn shared(t: T) -> Shared { - Arc::new(Mutex::new(t)) + Arc::new(RwLock::new(t)) } impl CratesIoStorage { @@ -109,7 +112,7 @@ impl CratesIoStorage { } pub async fn search(&self, query: &str) -> Vec<(String, Option, String)> { - let lock = self.data.lock().await; + let lock = self.data.read().await; if let Some(v) = &*lock { let search = v .predictive_search(query.to_lowercase()) @@ -151,7 +154,7 @@ impl CratesIoStorage { } pub async fn get_version_local(&self, name: &str) -> Option> { - let lock = self.data.lock().await; + let lock = self.data.read().await; if let Some(v) = &*lock { let search = v.exact_match(normalize_key(name))?; let (_, versions) = search @@ -164,7 +167,7 @@ impl CratesIoStorage { .collect::>(), ) } else { - let v = self.versions_cache.lock().await; + let v = self.versions_cache.read().await; match v.get(name) { Some(v) => match v { InfoCacheEntry::Pending(_) => None, @@ -200,7 +203,7 @@ impl CratesIoStorage { } pub async fn get_versions(&self, name: &str, version_filter: &str) -> Option> { - let lock = self.data.lock().await; + let lock = self.data.read().await; if let Some(v) = &*lock { let search = v.exact_match(normalize_key(name))?; let (_, versions) = search @@ -234,8 +237,8 @@ fn normalize_key(key: &str) -> String { pub fn update_thread(data: CratesIoStorage, path: PathBuf) { tokio::spawn(async move { let need_update = { - let updating = *data.updating.lock().await; - let last_checked = *data.last_checked.lock().await; + let updating = *data.updating.read().await; + let last_checked = *data.last_checked.read().await; match updating { true => false, false => match last_checked @@ -255,13 +258,13 @@ pub fn update_thread(data: CratesIoStorage, path: PathBuf) { } async fn update(toml_data: CratesIoStorage, path: &Path) { - *toml_data.updating.lock().await = true; + *toml_data.updating.write().await = true; let update = updated_local_git(path); if update { let data = read_data(path); - *toml_data.data.lock().await = data; + *toml_data.data.write().await = data; } - *toml_data.updating.lock().await = false; - *toml_data.last_checked.lock().await = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + *toml_data.updating.write().await = false; + *toml_data.last_checked.write().await = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); } diff --git a/src/lsp.rs b/src/lsp.rs index 9904594..f45f77b 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -49,9 +49,9 @@ impl Store { pub async fn needs_update( &self, - crates: &Arc>, + crates: &Shared, ) -> Vec<(String, RangeExclusive, String)> { - let lock = crates.lock().await; + let lock = crates.read().await; let mut updates = vec![]; for cr in self.crates_info.iter() { let crate_name = &cr.key.value; @@ -141,7 +141,7 @@ impl LanguageServer for Backend { .map(serde_json::from_value) .and_then(|v| v.ok()) .unwrap_or_default(); - *self.crates.lock().await = CratesIoStorage::new( + *self.crates.write().await = CratesIoStorage::new( &self.path, config.stable.unwrap_or(true), config.offline.unwrap_or(true), @@ -332,7 +332,7 @@ impl LanguageServer for Backend { //todo: use pub text_edit: let crate_ = &path[0]; if let KeyOrValueOwned::Key(key) = crate_ { - let result = self.crates.lock().await.search(&key.value).await; + let result = self.crates.read().await.search(&key.value).await; let v = result .into_iter() .map(|(name, detail, version)| CompletionItem { @@ -358,7 +358,7 @@ impl LanguageServer for Backend { KeyOrValueOwned::Value(Value::String { value, .. }) => { if let Some(v) = self .crates - .lock() + .read() .await .get_versions(&key.value, value) .await @@ -392,7 +392,7 @@ impl LanguageServer for Backend { { let v = self .crates - .lock() + .read() .await .get_features( &crate_.value, @@ -413,7 +413,7 @@ impl LanguageServer for Backend { "version}" => { if let Some(v) = self .crates - .lock() + .read() .await .get_versions(&crate_.value, value) .await