parallelize account loading and saving (#273)

- parallelize account loading
- parallelize account saving
This commit is contained in:
Carson McManus 2023-07-03 12:25:43 -04:00 committed by GitHub
parent 969baeed4c
commit 8f4ec79144
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 29 deletions

1
Cargo.lock generated
View file

@ -3078,6 +3078,7 @@ dependencies = [
"proptest", "proptest",
"qrcode", "qrcode",
"rand 0.8.5", "rand 0.8.5",
"rayon",
"regex", "regex",
"reqwest", "reqwest",
"rpassword", "rpassword",

View file

@ -67,6 +67,7 @@ keyring = { version = "2.0.4", optional = true }
argon2 = { version = "0.5.0", features = ["std"] } argon2 = { version = "0.5.0", features = ["std"] }
pbkdf2 = { version = "0.12.1", features = ["parallel"] } pbkdf2 = { version = "0.12.1", features = ["parallel"] }
sha1 = "0.10.5" sha1 = "0.10.5"
rayon = "1.7.0"
[dev-dependencies] [dev-dependencies]
tempdir = "0.3" tempdir = "0.3"

View file

@ -2,6 +2,7 @@ use crate::accountmanager::legacy::SdaManifest;
pub use crate::encryption::EncryptionScheme; pub use crate::encryption::EncryptionScheme;
use crate::encryption::EntryEncryptor; use crate::encryption::EntryEncryptor;
use log::*; use log::*;
use rayon::prelude::*;
use secrecy::{ExposeSecret, SecretString}; use secrecy::{ExposeSecret, SecretString};
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
@ -102,13 +103,14 @@ impl AccountManager {
/// Loads all accounts, and registers them. /// Loads all accounts, and registers them.
pub fn load_accounts(&mut self) -> anyhow::Result<(), ManifestAccountLoadError> { pub fn load_accounts(&mut self) -> anyhow::Result<(), ManifestAccountLoadError> {
let mut accounts = vec![]; let accounts = self
for entry in &self.manifest.entries { .manifest
let account = self.load_account_by_entry(entry)?; .entries
accounts.push(account); .par_iter()
} .map(|entry| self.load_account_by_entry(entry))
.collect::<Vec<_>>();
for account in accounts { for account in accounts {
self.register_loaded_account(account); self.register_loaded_account(account?);
} }
Ok(()) Ok(())
} }
@ -198,14 +200,15 @@ impl AccountManager {
/// Saves the manifest and all loaded accounts. /// Saves the manifest and all loaded accounts.
pub fn save(&self) -> anyhow::Result<()> { pub fn save(&self) -> anyhow::Result<()> {
info!("Saving manifest and accounts..."); info!("Saving manifest and accounts...");
for account in self let save_results: Vec<_> = self
.accounts .accounts
.values() .values()
.map(|a| a.clone().lock().unwrap().clone()) .par_bridge()
{ .map(|account| -> anyhow::Result<()> {
let account = account.lock().unwrap();
let entry = self.get_entry(&account.account_name)?.clone(); let entry = self.get_entry(&account.account_name)?.clone();
debug!("saving {}", entry.filename); debug!("saving {}", entry.filename);
let serialized = serde_json::to_vec(&account)?; let serialized = serde_json::to_vec(&account.clone())?;
ensure!( ensure!(
serialized.len() > 2, serialized.len() > 2,
"Something extra weird happened and the account was serialized into nothing." "Something extra weird happened and the account was serialized into nothing."
@ -225,6 +228,12 @@ impl AccountManager {
let mut file = File::create(path)?; let mut file = File::create(path)?;
file.write_all(final_buffer.as_slice())?; file.write_all(final_buffer.as_slice())?;
file.sync_data()?; file.sync_data()?;
Ok(())
})
.collect();
for result in save_results {
result?;
} }
debug!("saving manifest"); debug!("saving manifest");
let manifest_serialized = serde_json::to_string(&self.manifest)?; let manifest_serialized = serde_json::to_string(&self.manifest)?;