parallelize account loading and saving (#273)
- parallelize account loading - parallelize account saving
This commit is contained in:
parent
969baeed4c
commit
8f4ec79144
3 changed files with 40 additions and 29 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3078,6 +3078,7 @@ dependencies = [
|
||||||
"proptest",
|
"proptest",
|
||||||
"qrcode",
|
"qrcode",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rpassword",
|
"rpassword",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,33 +200,40 @@ 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 entry = self.get_entry(&account.account_name)?.clone();
|
let account = account.lock().unwrap();
|
||||||
debug!("saving {}", entry.filename);
|
let entry = self.get_entry(&account.account_name)?.clone();
|
||||||
let serialized = serde_json::to_vec(&account)?;
|
debug!("saving {}", entry.filename);
|
||||||
ensure!(
|
let serialized = serde_json::to_vec(&account.clone())?;
|
||||||
serialized.len() > 2,
|
ensure!(
|
||||||
"Something extra weird happened and the account was serialized into nothing."
|
serialized.len() > 2,
|
||||||
);
|
"Something extra weird happened and the account was serialized into nothing."
|
||||||
|
);
|
||||||
|
|
||||||
let final_buffer: Vec<u8> = match (&self.passkey, entry.encryption.as_ref()) {
|
let final_buffer: Vec<u8> = match (&self.passkey, entry.encryption.as_ref()) {
|
||||||
(Some(passkey), Some(scheme)) => {
|
(Some(passkey), Some(scheme)) => {
|
||||||
scheme.encrypt(passkey.expose_secret(), serialized)?
|
scheme.encrypt(passkey.expose_secret(), serialized)?
|
||||||
}
|
}
|
||||||
(None, Some(_)) => {
|
(None, Some(_)) => {
|
||||||
bail!("maFiles are encrypted, but no passkey was provided.");
|
bail!("maFiles are encrypted, but no passkey was provided.");
|
||||||
}
|
}
|
||||||
(_, None) => serialized,
|
(_, None) => serialized,
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = Path::new(&self.folder).join(&entry.filename);
|
let path = Path::new(&self.folder).join(&entry.filename);
|
||||||
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)?;
|
||||||
|
|
Loading…
Reference in a new issue