Commit Graph

47 Commits

Author SHA1 Message Date
claude code agent 444bd3e42f fix(stability): stage 2 — atomic media downloads, in-flight dedup, FloodWait->429, bounded semaphore
Fixes flaky static media serving: partial files served as 'ready', truncated
stubs living for an hour, and app-wide hangs under a saturated download path.

2.1 _download_atomic(file_id, final_path, timeout): downloads to a unique
    {final}.part.{hex}, validates size>0, and publishes solely via os.rename
    (atomic on POSIX); a finally ALWAYS removes the partial (timeout/cancel/
    zero-size/race-loser). Every downloader call routes through it, so a file at a
    FINAL name ({fid} / temp_{fid}) is GUARANTEED complete (grep-proven: the only
    safe_download_media caller passes a .part. path). Big-video timeout scales with
    size (min/max/min-speed knobs, documented in dockercompose.yml). The sweeper
    regex now matches both .part. and legacy .tmp. stubs.
2.2 In-flight dedup registry: the first request for a key runs the download in a
    DETACHED task sharing a Future; the task's finally sets the Future AND pops the
    key. Waiters await asyncio.shield(fut) so a client disconnect / waiter timeout
    cancels only the waiter, never the download — no hung waiters, no stuck key, a
    failed download frees the key for retry.
2.3 FloodWait->429: handler before except RPCError (FloodWait subclasses it),
    Retry-After = min(value + rand(1,30), 300); propagates from the detached task
    through the Future.
2.4 Serving a temp_* file touches its mtime so the 1h sweeper can't delete a
    video out from under a viewer.
2.5 The HTTP download semaphore acquire is bounded (wait_for 30 -> 503 +
    Retry-After); the permit is released only if the acquire succeeded. The
    request-scoped-permit trade-off (a disconnect can transiently exceed the
    download count) is documented inline for stage-7 prod observation.

Tests (tests/test_stage2_static.py, 13): atomic publish/clean on every exit incl.
FloodWait-through-the-finally; concurrent big-video serves no partial; dedup runs
one download, a cancelled waiter doesn't hang others, a failed download frees the
key; FloodWait -> 429; mtime touch; sweeper cleans .part./.tmp./stale temp_ but
keeps fresh files. 193 passed (180 baseline + 13).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 07:40:47 +03:00
vvzvlad 021f16cf14 feat(client): add watchdog heartbeat and diagnostics counters
Introduce `tg_watchdog_heartbeat_every` to emit periodic INFO heartbeats.
Add cumulative diagnostics counters and richer logging for watchdog probes,
restart reasons, and disconnect‑flap triggers. Update defaults and tests
accordingly.
2026-06-04 19:19:22 +03:00
vvzvlad 79b127d406 feat(client): add watchdog and disconnect flap handling
Introduce an active watchdog that probes the Telegram client to detect
zombie sessions and restart them in‑process. Add configurable disconnect
flap detection with a sliding window to trigger restarts after repeated
disconnects. New environment variables and config entries are added, and
the Kurigram dependency is now version‑pinned.
2026-06-04 19:02:09 +03:00
vvzvlad ab8f15d49d feat(api): add atomic temp file handling for media downloads
- Use unique temporary file paths with UUID to avoid race conditions during concurrent downloads.
- Perform atomic rename of the temp file to the final cache location and handle existing concurrent downloads.
- Clean up zero‑size and stale temporary files, including new “.tmp.<hex>” pattern.
- Extend cleanup logic to detect and remove race‑condition temp files.
- Validate and convert environment variables (TG_API_ID, TG_PROXY_PORT, API_PORT) with clear error messages and proper exit handling.
- Flush prints and replace `os._exit` with `sys.exit` for graceful termination.
- Fix URL regex in `PostParser` and guard against missing channel usernames when generating media URLs.
- Deep‑copy message lists in RSS generator to prevent mutation across calls.
- Propagate `FloodWait` exceptions to be handled by the API server instead of retrying internally.
- Enhance `TelegramClient` disconnect handling with a brief pause, shutdown check, and reconnection reset.
- Refine auth retry logic to check for actual `KeyError` instances.
2026-05-17 23:49:18 +03:00
vvzvlad 09692edf06 feat(config): add mtproto proxy support
Introduce optional MTProto proxy configuration sourced from environment variables, expose related settings in `config.py`, document the variables in `dockercompose.yml`, and pass the proxy configuration to the Telegram client initialization.
2026-04-05 18:09:23 +03:00
vvzvlad 02c29f8692 fix(telegram): add shutdown guard to avoid duplicate restarts
Add a `_shutting_down` flag to `TelegramClient` to suppress disconnect handling during intentional shutdown. The flag is set before sending SIGTERM in `_restart_app` and checked in `_on_disconnect` to ignore those events. Minor formatting adjustments were also applied to `api_server.py` (try block and `uvicorn.run` arguments).
2026-03-16 04:13:39 +03:00
vvzvlad 14f8db0a32 refactor(client): add optional session param to _on_disconnect 2026-03-16 04:05:39 +03:00
vvzvlad 3c2b4ce544 perf(downloads): implement concurrent download queue with semaphore limiting and retry logic
Add queue-based background download system to improve performance and reliability:
- Introduce DOWNLOAD_SEMAPHORE to limit concurrent downloads to 3
- Add asyncio.Queue (maxsize 100) with dedicated worker for background processing
- Implement safe_get_messages and safe_download_media wrappers with timeout protection (30s and 120s)
- Add retry logic for KeyError auth failures with 5s backoff
- Replace synchronous sequential downloads with asynchronous queued processing
- Prevent event loop blocking by queuing files instead of immediate download
2026-01-01 14:14:26 +03:00
vvzvlad 43516d6dab refactor api_server and TelegramClient: remove force_exit function and replace with sys.exit for process termination, update restart logic to use SIGTERM instead of SIGKILL for graceful shutdown 2025-06-10 15:03:09 +03:00
vvzvlad 521c3dc394 implement forceful termination in api_server and TelegramClient: add force_exit function for immediate process shutdown, update SIGTERM handler for forceful exit, and adjust restart logic in connection_handler to use SIGKILL 2025-06-10 14:28:51 +03:00
vvzvlad d6c3725b02 implement graceful shutdown in api_server: add SIGTERM handler for proper termination and enhance error handling for server startup issues 2025-06-10 14:06:56 +03:00
vvzvlad 2c9ebf139f refactor connection_handler in TelegramClient: increase wait time to 5 seconds before restart, implement process termination and forking for more reliable restarts 2025-06-10 03:58:33 +03:00
vvzvlad 223ae57929 add delay in connection_handler to ensure resources are freed before process restart 2025-06-10 03:38:33 +03:00
vvzvlad c94090c4b5 update _on_disconnect method in TelegramClient: change to async for better handling of disconnections 2025-06-10 03:25:54 +03:00
vvzvlad be28a11db6 implement connection handling in TelegramClient: add disconnect tracking and application restart on multiple disconnections 2025-04-27 18:31:29 +04:00
vvzvlad cb419c97af update pylint and pylance disable comments 2025-04-18 18:00:02 +03:00
vvzvlad 422e2adc2d Add shebang and encoding declaration to multiple Python files 2025-04-03 01:48:34 +03:00
vvzvlad 583a4c4b3c Add uvloop support for asyncio in api_server and telegram_client; update requirements.txt 2025-03-21 14:29:57 +03:00
vvzvlad 60b253c1c1 Refactor session handling and configuration management 2025-02-10 05:09:29 +03:00
vvzvlad b0e03ce6e8 Enhance media retrieval with file unique ID and improved error handling 2025-02-03 02:28:58 +03:00
vvzvlad 7d5f151793 Update media URL generation to include chat username and message ID 2025-02-03 02:06:51 +03:00
vvzvlad 1693e5c0b0 Add media file ID tracking and update file ID retrieval method 2025-02-02 23:35:07 +03:00
vvzvlad f360f1167c BIG refactoring 2025-02-02 18:51:50 +03:00
vvzvlad 2a6470462d Add channel title and icon to RSS feed generation 2025-02-02 03:56:42 +03:00
vvzvlad 533fc8ba31 Fix media URL handling by stripping leading slashes 2025-02-02 03:50:12 +03:00
vvzvlad ca0286a18b Skip pinned service messages in Telegram client parsing 2025-02-02 03:41:52 +03:00
vvzvlad 6b1e75946d Add support for Voice, Animation, and WebPage media types in Telegram client 2025-02-02 03:22:06 +03:00
vvzvlad 3ad9a6461b Enhance media parsing with comprehensive media type support and robust error handling 2025-02-02 02:58:36 +03:00
vvzvlad 1c190b69ac Refactor author information extraction in Telegram client 2025-02-02 02:22:39 +03:00
vvzvlad 2842cebcca Modify message parsing to include raw text, views, and media group ID 2025-02-02 02:15:18 +03:00
vvzvlad 9bb0d8a021 Add RSS feed generation endpoint for Telegram channels 2025-02-02 01:59:14 +03:00
vvzvlad d1ae60a14c Add configurable Pyrogram bridge URL and log level settings 2025-02-02 01:00:41 +03:00
vvzvlad 3f198ffa33 Enhance media parsing with web page photo and poll support 2025-02-02 00:49:47 +03:00
vvzvlad 63a3c4a988 Add media download endpoint and refactor media handling 2025-02-02 00:34:54 +03:00
vvzvlad 5bcac3f494 Disable complex text entity processing in Telegram client 2025-02-01 23:39:46 +03:00
vvzvlad 75a2cca8bd Improve media group processing and message retrieval in Telegram client 2025-02-01 21:11:14 +03:00
vvzvlad 96d316fcb5 Enhance Telegram message parsing with additional metadata extraction 2025-02-01 20:47:21 +03:00
vvzvlad e7f7520f79 Simplify media group processing and message parsing logic 2025-02-01 20:37:20 +03:00
vvzvlad f72b9af544 Add comprehensive raw message parsing and metadata extraction 2025-02-01 20:29:06 +03:00
vvzvlad 19f2c8b3cc Refactor Telegram message parsing and title generation 2025-02-01 20:19:18 +03:00
vvzvlad 6f1cca6646 Include author information in combined Telegram message result 2025-02-01 20:17:16 +03:00
vvzvlad 7a678bf08e Add author information extraction to Telegram message parsing 2025-02-01 20:15:22 +03:00
vvzvlad b33fb2e060 Improve title generation with better truncation logic 2025-02-01 20:12:03 +03:00
vvzvlad 8fe4a1e906 Add title generation for Telegram posts and improve media preview styling 2025-02-01 20:10:19 +03:00
vvzvlad bcac493e4b Enhance message parsing and HTML rendering for Telegram posts 2025-02-01 18:31:14 +03:00
vvzvlad 20221c78e1 add html support 2025-02-01 17:52:23 +03:00
vvzvlad 6e367b3ac9 first work version 2025-02-01 16:47:46 +03:00