Skip to content

feat(daemon): download scheduling windows and bandwidth throttling - #56

Open
rfsbraz wants to merge 1 commit into
mainfrom
feat/schedule-and-throttle
Open

feat(daemon): download scheduling windows and bandwidth throttling#56
rfsbraz wants to merge 1 commit into
mainfrom
feat/schedule-and-throttle

Conversation

@rfsbraz

@rfsbraz rfsbraz commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Fixes #36

  • New TDL_SCHEDULE_ACTIVE_HOURS setting gates daemon checks to configured time windows (24h local time via TZ); supports multiple comma-separated windows and windows that cross midnight (23:00-06:00)
  • Outside active hours the daemon logs the skip, keeps updating the health file, and never interrupts a download already in flight - the schedule only gates the start of a check
  • New TDL_MAX_DOWNLOAD_SPEED setting (e.g. 5MB) caps aggregate download speed via a shared async token-bucket limiter fed by pyrogram's progress callbacks, so throttling never blocks the event loop
  • Both settings validate at startup (clear config errors on bad formats) and default to unrestricted
  • Unit tests cover window parsing, cross-midnight logic, the daemon gate, rate parsing and throttle timing; README documents both settings

Copilot AI review requested due to automatic review settings July 5, 2026 08:44
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Testing this PR

Option 1 — Docker Compose override:

Create a docker-compose.override.yml:

services:
  telegram-downloader:
    build: https://github.com/rfsbraz/telegram-downloader.git#refs/pull/56/head

Then run:

docker compose up --build

Option 2 — Direct build and run:

docker build https://github.com/rfsbraz/telegram-downloader.git#refs/pull/56/head -t telegram-downloader:pr-56
docker run --rm -it telegram-downloader:pr-56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds two user-configurable controls to the daemon: (1) scheduling windows that gate when a daemon check can start, and (2) an optional aggregate bandwidth cap applied during downloads via a shared async rate limiter.

Changes:

  • Introduces TDL_SCHEDULE_ACTIVE_HOURS parsing + daemon gating to skip checks outside configured time windows.
  • Introduces TDL_MAX_DOWNLOAD_SPEED parsing + a shared async token-bucket limiter wired into Pyrogram download progress.
  • Adds unit tests and README documentation for both settings, plus startup validation in config schema.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/unit/daemon/test_schedule.py Adds unit tests for active-hours parsing, cross-midnight behavior, and daemon check gating.
tests/unit/daemon/init.py Marks daemon unit test package.
tests/unit/client/test_ratelimit.py Adds unit tests for rate parsing and RateLimiter throttling behavior.
src/main.py Wires optional RateLimiter into download flows and passes schedule config into DaemonService.
src/daemon/service.py Adds active_hours configuration and gates run_check() based on parsed schedule windows.
src/daemon/schedule.py Implements active-hours parsing and “within window” checks (including cross-midnight).
src/config/schema.py Adds schedule_active_hours and max_download_speed config fields with startup validation.
src/config/loader.py Allows the new config keys to be loaded from environment variables.
src/client/ratelimit.py Implements parse_rate() and an async shared token-bucket RateLimiter.
src/client/downloader.py Hooks the optional limiter into progress callbacks by feeding byte deltas to the limiter.
README.md Documents scheduling and bandwidth environment variables and expected formats.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main.py
limiter = None
if cfg.max_download_speed:
limiter = RateLimiter(parse_rate(cfg.max_download_speed))
log.info(f"Download speed capped at {cfg.max_download_speed}/s")
Comment thread src/client/ratelimit.py
"GB": 1024 ** 3,
}

_RATE_RE = re.compile(r"^([\d.]+)\s*([A-Z]+)?(?:/S)?$")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: download scheduling and bandwidth controls

2 participants