radicle: Load inventory lazily
Instead of loading the inventory cache on storage open, load it when the `inventory` function is called and the cache is `None`.
This commit is contained in:
parent
057af40ea3
commit
6288dd0a24
|
|
@ -790,6 +790,7 @@ where
|
||||||
}
|
}
|
||||||
Command::UpdateInventory(rid, resp) => {
|
Command::UpdateInventory(rid, resp) => {
|
||||||
self.storage.insert(rid);
|
self.storage.insert(rid);
|
||||||
|
|
||||||
let synced = self
|
let synced = self
|
||||||
.sync_inventory()
|
.sync_inventory()
|
||||||
.expect("Service::command: error syncing inventory");
|
.expect("Service::command: error syncing inventory");
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@ impl<'a> TryFrom<git2::Reference<'a>> for Ref {
|
||||||
pub struct Storage {
|
pub struct Storage {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
info: UserInfo,
|
info: UserInfo,
|
||||||
inventory: Arc<Mutex<BTreeSet<RepoId>>>,
|
/// Inventory cache. Set to `None` until the cache is populated.
|
||||||
|
inventory: Arc<Mutex<Option<BTreeSet<RepoId>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadStorage for Storage {
|
impl ReadStorage for Storage {
|
||||||
|
|
@ -116,24 +117,31 @@ impl ReadStorage for Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inventory(&self) -> Result<Inventory, Error> {
|
fn inventory(&self) -> Result<Inventory, Error> {
|
||||||
match self.inventory.lock() {
|
let mut cache = self
|
||||||
Ok(locked) => Ok(locked.clone()),
|
.inventory
|
||||||
Err(poisoned) => {
|
.lock()
|
||||||
let inv = poisoned.into_inner();
|
.unwrap_or_else(|poisoned| poisoned.into_inner());
|
||||||
Ok(inv.clone())
|
|
||||||
|
match *cache {
|
||||||
|
Some(ref cache) => Ok(cache.clone()),
|
||||||
|
None => {
|
||||||
|
let repos: BTreeSet<_> = self.public_repositories()?.collect();
|
||||||
|
*cache = Some(repos.clone());
|
||||||
|
Ok(repos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&self, rid: RepoId) {
|
fn insert(&self, rid: RepoId) {
|
||||||
match self.inventory.lock() {
|
let mut repos = self
|
||||||
Ok(mut locked) => {
|
.inventory
|
||||||
locked.insert(rid);
|
.lock()
|
||||||
}
|
.unwrap_or_else(|poisoned| poisoned.into_inner());
|
||||||
Err(poisoned) => {
|
|
||||||
let mut inv = poisoned.into_inner();
|
// If the cache hasn't been populated yet, we don't do anything, since this repo
|
||||||
inv.insert(rid);
|
// will be loaded when the cache is populated.
|
||||||
}
|
if let Some(ref mut repos) = *repos {
|
||||||
|
repos.insert(rid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,14 +186,11 @@ impl Storage {
|
||||||
Err(err) => return Err(Error::Io(err)),
|
Err(err) => return Err(Error::Io(err)),
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
}
|
}
|
||||||
let storage = Self {
|
Ok(Self {
|
||||||
path,
|
path,
|
||||||
info,
|
info,
|
||||||
inventory: Arc::new(Mutex::new(BTreeSet::new())),
|
inventory: Default::default(),
|
||||||
};
|
})
|
||||||
storage.refresh()?;
|
|
||||||
|
|
||||||
Ok(storage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [`Repository`] in a temporary directory.
|
/// Create a [`Repository`] in a temporary directory.
|
||||||
|
|
@ -306,24 +311,12 @@ impl Storage {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh(&self) -> Result<(), Error> {
|
fn public_repositories(&self) -> Result<impl Iterator<Item = RepoId>, Error> {
|
||||||
let repos = self.repositories()?;
|
let repos = self.repositories()?;
|
||||||
let rids = repos
|
Ok(repos
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|r| r.doc.visibility.is_public())
|
.filter(|r| r.doc.visibility.is_public())
|
||||||
.map(|r| r.rid)
|
.map(|r| r.rid))
|
||||||
.collect();
|
|
||||||
|
|
||||||
match self.inventory.lock() {
|
|
||||||
Ok(mut locked) => {
|
|
||||||
*locked = rids;
|
|
||||||
}
|
|
||||||
Err(poisoned) => {
|
|
||||||
let mut inv = poisoned.into_inner();
|
|
||||||
*inv = rids;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue