perf(*): bound list queries, batch fetches, harden media downloads

This commit is contained in:
hh committed 2026-09-01 21:38:22 +02:00
1 parent 9c12628304
commit 1fa4f18a9b
35 files changed
+473 -138

No files matched your search

@@ -1,5 +1,5 @@
from pyrogram import Client
from pyrogram.errors import PeerIdInvalid
from pyrogram.errors import FloodPremiumWait, FloodWait, PeerIdInvalid
from pyrogram.types import Message
from userbot.modules.capture import capture_message
@@ -11,6 +11,7 @@ from userbot.modules.jobs.registry import register
from userbot.modules.stt import repository as stt_repo
from userbot.modules.stt import should_transcribe_on_backfill
from userbot.modules.stt.gate import safe_transcribe
from utils.logging import logger
from utils.policy.models import CaptureToggles
SAVE_EVERY = 100
@@ -61,21 +62,30 @@ async def backfill(ctx: JobContext) -> None:
min_id = await resolve_min_id(ctx, chat_id)
await ctx.save_cursor({"max_id": max_id, "min_id": min_id})
processed = ctx.job.progress.get("processed", 0)
errors = ctx.job.progress.get("errors", 0)
self_id = client.me.id if client.me else None
try:
async for message in client.get_chat_history(
chat_id, max_id=max_id, min_id=min_id
):
await capture_message(client, message, capture, toggles)
await maybe_transcribe(client, capture, chat_id, message, self_id)
try:
await capture_message(client, message, capture, toggles)
await maybe_transcribe(client, capture, chat_id, message, self_id)
except (FloodWait, FloodPremiumWait, PeerIdInvalid):
raise
except Exception:
errors += 1
logger.exception(f"Backfill capture failed for {chat_id}/{message.id}")
processed += 1
if processed % SAVE_EVERY == 0:
next_max = message.id - 1
await ctx.save_cursor({"max_id": next_max, "min_id": min_id})
await ctx.report_progress({"processed": processed, "max_id": next_max})
await ctx.report_progress(
{"processed": processed, "errors": errors, "max_id": next_max}
)
if await ctx.is_canceled():
return
except PeerIdInvalid:
await ctx.report_progress({"processed": processed, "error": "peer_id_invalid"})
return
await ctx.report_progress({"processed": processed, "done": True})
await ctx.report_progress({"processed": processed, "errors": errors, "done": True})
@@ -65,16 +65,28 @@ async def _enrich_members(client: Client, ctx: CaptureContext, chat_id: int) ->
return
async def _fetch_users(client: Client, ids: list[int]) -> list[User]:
try:
users = await client.get_users(ids)
except BadRequest:
users = []
for sender_id in ids:
try:
users.append(await client.get_users(sender_id))
except BadRequest:
continue
if isinstance(users, User):
return [users]
return [user for user in users if isinstance(user, User)]
async def _enrich_senders(client: Client, ctx: CaptureContext, chat_id: int) -> None:
rows = await ctx.pool.fetch(_MISSING_SENDERS, ctx.account_id, chat_id)
ids = [row["sender_id"] for row in rows]
for sender_id in ids:
try:
user = await client.get_users(sender_id)
except BadRequest:
continue
if isinstance(user, User):
await _save_user(ctx, user)
if not ids:
return
for user in await _fetch_users(client, ids):
await _save_user(ctx, user)
@register("enrich_chat")
@@ -18,6 +18,10 @@ async def fetch_media(ctx: JobContext) -> None:
if isinstance(message, list):
message = message[0] if message else None
if message is None or message.empty:
return
msg = f"message {chat_id}/{message_id} is unavailable"
raise RuntimeError(msg)
toggles = CaptureToggles(media=True, self_destruct_media=True)
await capture_media(client, message, capture, chat_id, message_id, toggles)
ok = await capture_media(client, message, capture, chat_id, message_id, toggles)
if not ok:
msg = f"media download failed for {chat_id}/{message_id}"
raise RuntimeError(msg)