perf(*): bound list queries, batch fetches, harden media downloads
This commit is contained in:
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)
|
||||
Reference in new issue
Block a user