perf(core): improve async handling and caching performance

Convert delayed_delete_file to async and use asyncio.sleep.
Add pre‑semaphore cache hit to serve cached files without acquiring the download semaphore.
Set SQLite busy_timeout to reduce lock errors.
Introduce a diagnostics counter for pending _persist_media_file_id_async tasks.
Refactor flag extraction to accept pre‑generated HTML and compute html body once.
Batch reply enrichment in RSS generator to minimize API calls.
Store cached messages directly in tg_cache and add fallback for legacy double‑pickle format.

BREAKING CHANGE: delayed_delete_file is now async and must be awaited.
This commit is contained in:
vvzvlad
2026-05-18 00:08:46 +03:00
parent ab8f15d49d
commit f0e38b9776
5 changed files with 101 additions and 31 deletions
+8 -4
View File
@@ -42,11 +42,11 @@ def _save_history_to_cache(channel_id: Union[str, int], messages: List[Message],
try:
cache_file = _get_history_cache_file_path(channel_id)
# Create cache metadata
# Create cache metadata — store messages directly (no inner pickle.dumps)
cache_data = {
'timestamp': time.time(),
'limit': limit,
'messages': pickle.dumps(messages)
'messages': messages
}
with open(cache_file, 'wb') as f:
@@ -94,8 +94,12 @@ def _get_history_from_cache(channel_id: Union[str, int], limit: int, max_age_hou
logger.info(f"history_cache_limit_mismatch: channel {channel_id}, cached limit {cached_limit}, requested limit {limit}")
return None
# Restore message list from pickle
messages = pickle.loads(cache_data['messages'])
# Restore message list; handle old cache files that used double-pickle (bytes = old format)
raw = cache_data['messages']
if isinstance(raw, bytes):
messages = pickle.loads(raw)
else:
messages = raw
logger.info(f"history_cache_hit: channel {channel_id}, limit {limit}, messages {len(messages)}, age {cache_age:.1f}s")
return messages