diff --git a/PROJECT.md b/PROJECT.md index 416423c..f0e49be 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -56,3 +56,5 @@ All other functionality uses Python stdlib (`asyncio`, `socket`, `struct`). - **Weighted selection** -- recently-tested proxies preferred via recency decay weight - **Failure backoff** -- connection failures penalize proxy weight for 60s, avoids retry waste - **Stale expiry** -- proxies dropped from sources evicted after 3 refresh cycles if not alive +- **Chain pre-flight** -- static chain tested before pool health tests; skip on failure +- **Warm start** -- quick-test alive subset on restart, defer full test to background diff --git a/README.md b/README.md index 1151c08..1fd9d9e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ through configurable chains of SOCKS4, SOCKS5, and HTTP CONNECT proxies. - DNS leak prevention (domain names forwarded to proxies, never resolved locally) - Tor integration (Tor is just another SOCKS5 hop) - Managed proxy pool: multiple sources (API + file), health-tested, weighted selection -- Per-proxy failure backoff (60s cooldown) and stale proxy expiry +- Per-proxy failure backoff (60s cooldown), stale proxy expiry, chain pre-flight +- Fast warm start (seconds on restart vs minutes on cold start) - Connection retry with proxy rotation (configurable attempts) - Connection metrics with pool stats (logged periodically and on shutdown) - Container-ready (Alpine-based, podman/docker) diff --git a/ROADMAP.md b/ROADMAP.md index 3ab4ab1..f28810c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -15,12 +15,13 @@ - [x] Per-proxy backoff (connection failure cooldown) - [x] Stale proxy expiry (last_seen TTL) - [x] Pool stats in periodic metrics log +- [x] Fast warm start (deferred full health test) +- [x] Static chain health check (pre-flight before pool tests) ## v0.2.0 - [ ] SOCKS5 server authentication (username/password) - [ ] Tor control port integration (circuit renewal via NEWNYM) -- [ ] Parallel health tests at startup (fast warm start) - [ ] Metrics (connections/sec, bytes relayed, hop latency) ## v0.3.0 diff --git a/TASKS.md b/TASKS.md index a3a2fc9..79340a2 100644 --- a/TASKS.md +++ b/TASKS.md @@ -23,6 +23,8 @@ - [x] Per-proxy backoff (60s cooldown after connection failure) - [x] Stale proxy expiry (evict dead proxies not seen for 3 refresh cycles) - [x] Pool stats in periodic metrics log (`pool=alive/total`) +- [x] Fast warm start (quick-test alive subset, defer full test) +- [x] Static chain health check (skip pool tests if chain unreachable) ## Next - [ ] Integration tests with mock proxy server diff --git a/TODO.md b/TODO.md index d8c2a3d..47aee0d 100644 --- a/TODO.md +++ b/TODO.md @@ -7,9 +7,7 @@ - Per-destination chain rules (bypass chain for local addresses) - Hot config reload on SIGHUP - Systemd socket activation -- Parallel health tests at startup (fast warm start) - Report dead proxies back to source API -- Chain health check (test static chain before pool tests) ## Performance diff --git a/docs/CHEATSHEET.md b/docs/CHEATSHEET.md index afd4e00..cacd994 100644 --- a/docs/CHEATSHEET.md +++ b/docs/CHEATSHEET.md @@ -104,3 +104,5 @@ metrics: conn=142 ok=98 fail=44 retries=88 active=3 in=1.2M out=4.5M up=0h05m12s | Port in use | `fuser -k 1080/tcp` to free the port | | Container slow stop | Rebuild image after SIGTERM fix | | Proxy keeps failing | Backoff penalizes for 60s; check `pool=` in metrics | +| "static chain unreachable" | Tor/upstream hop is down; pool tests skipped | +| Slow startup | Normal on cold start; warm restarts use state file | diff --git a/docs/USAGE.md b/docs/USAGE.md index e2d86c9..b94e40f 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -131,6 +131,11 @@ Each cycle tests all proxies through the full chain (static chain + proxy) by sending an HTTP GET to `test_url`. Proxies are marked alive on `200` response. After `max_fails` consecutive failures, a proxy is evicted. +Before each health test cycle, the static chain is tested without any pool +proxy. If the chain itself is unreachable (e.g., Tor is down), proxy tests +are skipped entirely and a warning is logged. This prevents false mass-failure +and unnecessary evictions. + Mass-failure guard: if >90% of tests fail in one cycle, eviction is skipped (likely the static chain is broken, not the proxies). @@ -167,6 +172,14 @@ Pool state is saved to `state_file` (default: `~/.cache/s5p/pool.json`) after each refresh/health cycle and on shutdown. On startup, previously-alive proxies are loaded for fast warm starts. +### Warm start + +When restarting with an existing state file, only the previously-alive proxies +are tested before the server starts accepting connections. A full health test +of all proxies runs in the background. This reduces startup blocking from +minutes to seconds on warm restarts. Cold starts (no state file) test all +proxies before serving. + ### CLI shorthand ```bash