From 281c4a262b54727e081154a6c0d8277e5f5c60b3 Mon Sep 17 00:00:00 2001 From: StNicolay Date: Sun, 1 Jan 2023 00:18:57 +0300 Subject: [PATCH] _export2 no longer blocks event loop during decryption Removed sorting in get_all_accounts Removed decrypt_multiple function because it is no longer used Now running decrytion of accounts in ProcessPoolExecutor --- src/bot/message_handlers.py | 13 ++++++++++++- src/database/get.py | 8 ++------ src/encryption/other_accounts.py | 10 ---------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/bot/message_handlers.py b/src/bot/message_handlers.py index 6baa371..db26995 100644 --- a/src/bot/message_handlers.py +++ b/src/bot/message_handlers.py @@ -1,5 +1,7 @@ +import asyncio import functools import gc +from concurrent.futures import ProcessPoolExecutor import telebot from sqlalchemy.future import Engine @@ -534,7 +536,16 @@ async def _export2( ) accounts = database.get.get_all_accounts(engine, mes.from_user.id) - accounts = encryption.other_accounts.decrypt_multiple(accounts, text) + with ProcessPoolExecutor() as pool: + loop = asyncio.get_running_loop() + tasks = [] + for account in accounts: + function = functools.partial( + encryption.other_accounts.decrypt, account, text + ) + tasks.append(loop.run_in_executor(pool, function)) + accounts = await asyncio.gather(*tasks) + accounts.sort(key=lambda account: account.name) json_io = accounts_to_json(accounts) await bot.send_document( mes.chat.id, diff --git a/src/database/get.py b/src/database/get.py index 7eb8a43..9830ae2 100644 --- a/src/database/get.py +++ b/src/database/get.py @@ -36,12 +36,8 @@ def get_accounts( def get_all_accounts(engine: Engine, user_id: int) -> list[models.Account]: """Returns a list of accounts of a user""" - statement = ( - sqlmodel.select(models.Account) - .where( - models.Account.user_id == user_id, - ) - .order_by(models.Account.name) + statement = sqlmodel.select(models.Account).where( + models.Account.user_id == user_id, ) with sqlmodel.Session(engine) as session: result = session.exec(statement).fetchall() diff --git a/src/encryption/other_accounts.py b/src/encryption/other_accounts.py index 30daea6..0c7d3d4 100644 --- a/src/encryption/other_accounts.py +++ b/src/encryption/other_accounts.py @@ -1,6 +1,5 @@ import base64 import os -from typing import Iterable, Iterator from cryptography.fernet import Fernet from cryptography.hazmat.backends import default_backend @@ -71,12 +70,3 @@ def decrypt( login=login, password=password, ) - - -def decrypt_multiple( - accounts: Iterable[Account], master_pass: str -) -> Iterator[DecryptedAccount]: - """Decrypts an iterable of accounts using master_pass and - returns an Iterator of decrypted accounts""" - for account in accounts: - yield decrypt(account, master_pass)