diff --git a/freva/src/drs/metadata.rs b/freva/src/drs/metadata.rs index eac10c9531181831dee91311040045fa15bddac7..d538979f4000d6240e0cccadda65ddc895dbf542 100644 --- a/freva/src/drs/metadata.rs +++ b/freva/src/drs/metadata.rs @@ -4,7 +4,7 @@ mod config_builder; pub mod custom; use core::fmt; -use std::sync::RwLock; +use std::sync::Mutex; use std::{ collections::HashMap, fmt::Formatter, @@ -21,7 +21,7 @@ use drs::{ use lazy_static::lazy_static; use netcdf::AttrValue; use thiserror::Error; -use tracing::{debug, error}; +use tracing::{debug, error, trace}; pub use config_builder::ConfigBuilder; use custom::Custom; @@ -395,26 +395,29 @@ lazy_static! { /// This is done as a global cache right now just because performance shouldn't be a large concern as we expect far /// more reads than writes and this implementation is simpler than e.g. having the [`drs`] crate load and hold the /// mapping values ahead of time. - static ref CMIP6_ATTR_CACHE: RwLock<HashMap<String, (String, String)>> = - RwLock::new(HashMap::new()); + static ref CMIP6_ATTR_CACHE: Mutex<HashMap<String, (String, String)>> = + Mutex::new(HashMap::new()); } /// Transforms a [`Cmip6`] object into [`Metadata`]. This is handled differently from the others because CMIP6's path /// does not contain all the data [`Metadata`] needs. To get the rest we need to either use mapping tables maintained /// separately from the DRS spec or, as we do here, open the files up and pull the data from their attributes. fn metadata_from_cmip6(cmip: Cmip6, root_dir: &Utf8Path) -> Result<Metadata, ExtractMetadataError> { - let (frequency, realm) = - if let Some((freq, realm)) = CMIP6_ATTR_CACHE.read().unwrap().get(cmip.metadata.table_id) { + let (frequency, realm) = { + let mut guard = CMIP6_ATTR_CACHE.lock().unwrap(); + if let Some((freq, realm)) = guard.get(cmip.metadata.table_id) { (freq.clone(), realm.clone()) } else { + trace!("attributes not cached, opening file to extract"); let (frequency, realm) = get_cmip6_attrs(&root_dir.join(cmip.path))?; - CMIP6_ATTR_CACHE.write().unwrap().insert( + guard.insert( cmip.metadata.table_id.to_owned(), (frequency.clone(), realm.clone()), ); (frequency, realm) - }; + } + }; let m = &cmip.metadata; Ok(Metadata {