import.rs now uses the FuturesUnordered to remove a mutex around the vector of failed accounts
This commit is contained in:
parent
7f949e3cdc
commit
2c69882b13
@ -3,13 +3,13 @@ use crate::{
|
|||||||
handlers::{markups::deletion_markup, utils::package_handler, MainDialogue, State},
|
handlers::{markups::deletion_markup, utils::package_handler, MainDialogue, State},
|
||||||
models::{DecryptedAccount, User},
|
models::{DecryptedAccount, User},
|
||||||
};
|
};
|
||||||
use futures::{stream, StreamExt, TryStreamExt};
|
use futures::{future, stream::FuturesUnordered, StreamExt, TryStreamExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use sea_orm::prelude::*;
|
use sea_orm::prelude::*;
|
||||||
use serde_json::from_slice;
|
use serde_json::from_slice;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use teloxide::{adaptors::Throttle, net::Download, prelude::*};
|
use teloxide::{adaptors::Throttle, net::Download, prelude::*};
|
||||||
use tokio::{sync::Mutex, task::spawn_blocking};
|
use tokio::task::spawn_blocking;
|
||||||
|
|
||||||
/// Gets the master password, encryptes and adds the accounts to the DB
|
/// Gets the master password, encryptes and adds the accounts to the DB
|
||||||
async fn get_master_pass(
|
async fn get_master_pass(
|
||||||
@ -21,40 +21,33 @@ async fn get_master_pass(
|
|||||||
accounts: Vec<DecryptedAccount>,
|
accounts: Vec<DecryptedAccount>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||||
|
let failed: Vec<String> = {
|
||||||
let master_pass: Arc<str> = master_pass.into();
|
let master_pass: Arc<str> = master_pass.into();
|
||||||
let failed = Arc::new(Mutex::new(Vec::new()));
|
let db = &db;
|
||||||
stream::iter(accounts)
|
let futures: FuturesUnordered<_> = accounts
|
||||||
.for_each_concurrent(None, |account| {
|
.into_iter()
|
||||||
|
.map(|account| {
|
||||||
let master_pass = Arc::clone(&master_pass);
|
let master_pass = Arc::clone(&master_pass);
|
||||||
let failed = Arc::clone(&failed);
|
|
||||||
let db = db.clone();
|
|
||||||
let name = account.name.clone();
|
|
||||||
async move {
|
async move {
|
||||||
let result = spawn_blocking(move || {
|
|
||||||
if !account.validate() {
|
if !account.validate() {
|
||||||
return Err(());
|
return Err(account.name);
|
||||||
}
|
}
|
||||||
account.into_account(user_id, &master_pass).map_err(|_| ())
|
let name = account.name.clone();
|
||||||
})
|
match spawn_blocking(move || account.into_account(user_id, &master_pass)).await
|
||||||
.await;
|
{
|
||||||
match result {
|
Ok(Ok(account)) => match account.insert(db).await {
|
||||||
Ok(Ok(account)) => match account.insert(&db).await {
|
Ok(_) => Ok(()),
|
||||||
Ok(_) => (),
|
Err(_) => Err(name),
|
||||||
Err(_) => failed.lock().await.push(name),
|
|
||||||
},
|
},
|
||||||
_ => failed.lock().await.push(name),
|
_ => Err(name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.collect();
|
||||||
drop(master_pass);
|
futures
|
||||||
let failed = match Arc::try_unwrap(failed) {
|
.filter_map(|result| future::ready(result.err()))
|
||||||
Ok(accounts) => accounts.into_inner(),
|
.collect()
|
||||||
Err(_) => {
|
.await
|
||||||
return Err(crate::Error::msg(
|
|
||||||
"Couldn't get accounts from Arc in import.rs",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let message = if failed.is_empty() {
|
let message = if failed.is_empty() {
|
||||||
"Success".to_owned()
|
"Success".to_owned()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user