Added more paralization to allow better multi-user perfomace

This commit is contained in:
StNicolay 2023-05-04 18:27:19 +03:00
parent ecf74fb50f
commit 17e4f1892c
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
6 changed files with 30 additions and 23 deletions

1
Cargo.lock generated
View File

@ -1569,6 +1569,7 @@ dependencies = [
"anyhow", "anyhow",
"chacha20poly1305", "chacha20poly1305",
"dotenv", "dotenv",
"futures",
"log", "log",
"migration", "migration",
"pbkdf2", "pbkdf2",

View File

@ -15,6 +15,7 @@ members = [".", "migration"]
anyhow = "1.0.70" anyhow = "1.0.70"
chacha20poly1305 = { version = "0.10.1", features = ["std"] } chacha20poly1305 = { version = "0.10.1", features = ["std"] }
dotenv = "0.15.0" dotenv = "0.15.0"
futures = "0.3.28"
log = "0.4.17" log = "0.4.17"
migration = { version = "0.1.0", path = "migration" } migration = { version = "0.1.0", path = "migration" }
pbkdf2 = "0.12.1" pbkdf2 = "0.12.1"

View File

@ -1,6 +1,7 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
use chacha20poly1305::{aead::Aead, AeadCore, ChaCha20Poly1305, KeyInit}; use chacha20poly1305::{aead::Aead, AeadCore, ChaCha20Poly1305, KeyInit};
use futures::{Stream, StreamExt};
use pbkdf2::pbkdf2_hmac_array; use pbkdf2::pbkdf2_hmac_array;
use rand::{rngs::OsRng, RngCore}; use rand::{rngs::OsRng, RngCore};
use sea_orm::{prelude::*, ActiveValue::Set, QuerySelect}; use sea_orm::{prelude::*, ActiveValue::Set, QuerySelect};
@ -88,14 +89,18 @@ impl Model {
impl Entity { impl Entity {
/// Gets a list of account names of a user /// Gets a list of account names of a user
pub async fn get_names(user_id: u64, db: &DatabaseConnection) -> crate::Result<Vec<String>> { pub async fn get_names(
Self::find() user_id: u64,
db: &DatabaseConnection,
) -> crate::Result<impl Stream<Item = crate::Result<String>> + '_> {
let result = Self::find()
.select_only() .select_only()
.column(Column::Name) .column(Column::Name)
.filter(Column::UserId.eq(user_id)) .filter(Column::UserId.eq(user_id))
.into_tuple() .into_tuple()
.all(db) .stream(db)
.await .await?
.map_err(|err| err.into()) .map(|item| item.map_err(Into::into));
Ok(result)
} }
} }

View File

@ -2,6 +2,7 @@ use crate::entity::account;
use crate::handlers::{utils::package_handler, MainDialogue, State}; use crate::handlers::{utils::package_handler, MainDialogue, State};
use sea_orm::prelude::*; use sea_orm::prelude::*;
use teloxide::{adaptors::Throttle, prelude::*}; use teloxide::{adaptors::Throttle, prelude::*};
use tokio::task::spawn_blocking;
async fn get_master_pass( async fn get_master_pass(
bot: Throttle<Bot>, bot: Throttle<Bot>,
@ -13,15 +14,13 @@ async fn get_master_pass(
password: String, password: String,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
let user_id = msg.from().unwrap().id.0;
let _ = bot.delete_message(msg.chat.id, msg.id).await; let _ = bot.delete_message(msg.chat.id, msg.id).await;
dialogue.exit().await?; dialogue.exit().await?;
let account = account::ActiveModel::from_unencrypted( let account = spawn_blocking(move || {
msg.from().unwrap().id.0, account::ActiveModel::from_unencrypted(user_id, name, &login, &password, &master_pass)
name, })
&login, .await??;
&password,
&master_pass,
)?;
account.insert(&db).await?; account.insert(&db).await?;
bot.send_message(msg.chat.id, "Success").await?; bot.send_message(msg.chat.id, "Success").await?;
Ok(()) Ok(())

View File

@ -1,8 +1,8 @@
use crate::entity::{account, prelude::Account}; use crate::entity::{account, prelude::Account};
use crate::handlers::{utils::package_handler, MainDialogue, State};
use sea_orm::prelude::*; use sea_orm::prelude::*;
use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode}; use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode};
use tokio::task::spawn_blocking;
use crate::handlers::{utils::package_handler, MainDialogue, State};
async fn get_master_pass( async fn get_master_pass(
bot: Throttle<Bot>, bot: Throttle<Bot>,
@ -20,7 +20,7 @@ async fn get_master_pass(
.one(&db) .one(&db)
.await? .await?
.unwrap(); .unwrap();
let (login, password) = account.decrypt(&master_pass)?; let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??;
let message = format!("Name:\n`{name}`\nLogin:\n`{login}`\nPassword:\n`{password}`"); let message = format!("Name:\n`{name}`\nLogin:\n`{login}`\nPassword:\n`{password}`");
bot.send_message(msg.chat.id, message) bot.send_message(msg.chat.id, message)
.parse_mode(ParseMode::MarkdownV2) .parse_mode(ParseMode::MarkdownV2)

View File

@ -1,4 +1,5 @@
use crate::entity::prelude::Account; use crate::entity::prelude::Account;
use futures::TryStreamExt;
use sea_orm::prelude::*; use sea_orm::prelude::*;
use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode}; use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode};
@ -8,20 +9,20 @@ pub async fn get_accounts(
db: DatabaseConnection, db: DatabaseConnection,
) -> crate::Result<()> { ) -> crate::Result<()> {
let user_id = msg.from().unwrap().id.0; let user_id = msg.from().unwrap().id.0;
let mut account_names = Account::get_names(user_id, &db).await?.into_iter(); let mut account_names = Account::get_names(user_id, &db).await?;
let mut result = match account_names.next() { let mut result = match account_names.try_next().await? {
Some(name) => format!("Accounts:\n`{name}`"), Some(name) => format!("Accounts:\n`{name}`"),
None => { None => {
bot.send_message(msg.chat.id, "No accounts found").await?; bot.send_message(msg.chat.id, "No accounts found").await?;
return Ok(()); return Ok(());
} }
}; };
for name in account_names { account_names
result.reserve(name.len() + 3); .try_for_each(|name| {
result.push_str("\n`"); result.push_str(&format!("\n`{}`", name));
result.push_str(&name); async { Ok(()) }
result.push('`') })
} .await?;
bot.send_message(msg.chat.id, result) bot.send_message(msg.chat.id, result)
.parse_mode(ParseMode::MarkdownV2) .parse_mode(ParseMode::MarkdownV2)
.await?; .await?;