Harden bot against runtime stalls

This commit is contained in:
Андрей Цой
2026-07-01 20:35:50 +09:00
parent 6fbe4c4f43
commit 26c65b7caa
18 changed files with 645 additions and 337 deletions

View File

@@ -15,7 +15,8 @@ class AccountParticipationService:
async def add_account_to_lottery(
session: AsyncSession,
lottery_id: int,
account_number: str
account_number: str,
commit: bool = True,
) -> Dict[str, Any]:
"""
Добавить счет в розыгрыш.
@@ -91,7 +92,10 @@ class AccountParticipationService:
account_id=account_record.id if account_record else None
)
session.add(participation)
await session.commit()
if commit:
await session.commit()
else:
await session.flush()
card_info = f" (карта: {card_number})" if card_number else ""
return {
@@ -120,7 +124,7 @@ class AccountParticipationService:
for account in account_numbers:
result = await AccountParticipationService.add_account_to_lottery(
session, lottery_id, account
session, lottery_id, account, commit=False
)
if result["success"]:
@@ -132,6 +136,8 @@ class AccountParticipationService:
results["skipped_accounts"].append(account)
results["errors"].append(result["message"])
results["details"].append(f"{result['message']}")
await session.commit()
return results
@@ -139,7 +145,8 @@ class AccountParticipationService:
async def remove_account_from_lottery(
session: AsyncSession,
lottery_id: int,
account_number: str
account_number: str,
commit: bool = True,
) -> Dict[str, Any]:
"""Удалить счет из розыгрыша"""
formatted_account = format_account_number(account_number)
@@ -164,7 +171,10 @@ class AccountParticipationService:
}
await session.delete(participation)
await session.commit()
if commit:
await session.commit()
else:
await session.flush()
return {
"success": True,
@@ -216,13 +226,21 @@ class AccountParticipationService:
pattern: Паттерн поиска (например "11-22" или "33")
limit: Максимальное количество результатов
"""
# Получаем все счета розыгрыша
all_accounts = await AccountParticipationService.get_lottery_accounts(
session, lottery_id
digits_pattern = ''.join(c for c in pattern if c.isdigit())
if not digits_pattern:
return []
result = await session.execute(
select(Participation.account_number)
.where(
Participation.lottery_id == lottery_id,
Participation.account_number.isnot(None),
func.replace(Participation.account_number, '-', '').contains(digits_pattern),
)
.order_by(Participation.created_at.desc())
.limit(limit)
)
# Ищем совпадения
return search_accounts_by_pattern(pattern, all_accounts)[:limit]
return [account for account in result.scalars().all() if account]
@staticmethod
async def set_account_as_winner(