stygian-proxy
High-performance, resilient proxy rotation for the Stygian scraping ecosystem.
Features
| Feature | Description | Default |
|---|---|---|
| Rotation strategies | Round-robin, random, weighted, least-used | ✓ |
| Circuit breakers | Per-proxy failure tracking & recovery | ✓ |
| Health checking | Background async health prober | ✓ |
| RAII proxy handles | Automatic success/failure recording on drop | ✓ |
socks |
SOCKS4/5 proxy support via reqwest | — |
graph |
Integration with stygian-graph HTTP adapters | — |
browser |
Integration with stygian-browser pool (ProxyManagerBridge + ProxyLeaseAdapter) |
— |
tls-profiled |
TLS fingerprint profiling for proxy connections (requires browser feature) |
— |
mcp |
MCP (Model Context Protocol) tools | — |
Features (Core Capabilities)
Installation
[]
= "*"
= { = "1", = ["full"] }
Enable optional features:
# SOCKS4/5 proxy support
= { = "*", = ["socks"] }
# Integration with stygian-graph HTTP adapters
= { = "*", = ["graph"] }
# Integration with stygian-browser pool
= { = "*", = ["browser"] }
Quick Start
use ;
use Arc;
use Duration;
async
Rotation Strategies
| Strategy | Constructor | Behaviour |
|---|---|---|
RoundRobinStrategy |
ProxyManager::with_round_robin |
Cycles through healthy proxies in order |
RandomStrategy |
ProxyManager::with_random |
Picks a healthy proxy at random each time |
WeightedStrategy |
ProxyManager::with_weighted |
Selects proportionally to each proxy's weight field |
LeastUsedStrategy |
ProxyManager::with_least_used |
Prefers the proxy with the lowest total request count |
Custom strategies implement RotationStrategy:
use ;
use ProxyResult;
use async_trait;
;
Circuit Breaker
Each proxy has its own CircuitBreaker. After circuit_open_threshold consecutive failures the breaker opens, and the proxy is excluded from rotation for circuit_half_open_after. After that window the proxy is tried once in HalfOpen state — a success closes it; another failure reopens it.
use ;
use Arc;
use Duration;
let config = ProxyConfig ;
let manager = with_round_robin?;
If a ProxyHandle is dropped without calling mark_success(), the circuit breaker records a failure automatically.
Health Checking
ProxyManager::start() spawns a background task that probes each proxy on a configurable interval and updates per-proxy health scores:
use ;
use Arc;
use Duration;
let config = ProxyConfig ;
let manager = with_round_robin?;
let = manager.start;
// Graceful shutdown
cancel_token.cancel;
stygian-graph Integration
With the graph feature, the pool implements ProxyManagerPort so stygian-graph adapters can rotate proxies per-request:
= { = "*", = ["graph"] }
= "*"
use ;
use ProxyConfig;
use Arc;
let manager = with_round_robin?;
// Pass as Arc<dyn ProxyManagerPort> to RestApiAdapter or HttpAdapter
stygian-browser Integration
With the browser feature, ProxyManagerBridge implements [stygian_browser::proxy::ProxySource] so
stygian-browser contexts can acquire live pool proxies at launch time:
= { = "*", = ["browser"] }
= "*"
use ;
use ProxyConfig;
use BrowserConfig;
use Arc;
let manager = new;
let bridge = new;
// Pass the bridge to browser config
let config = builder
.proxy_source
.build;
// Each browser context acquires its own proxy from the pool
// On release: proxy success/failure automatically recorded to circuit breaker
Under the hood:
ProxyManagerBridgeimplementsProxySource(browser's port trait)- Each acquired proxy is wrapped in
ProxyLeaseAdapter - When
mark_success()is called on the lease, it updates the proxy's circuit breaker - On drop without marked success, the proxy is recorded as failed
License
AGPL-3.0-only OR LicenseRef-Commercial — see LICENSE and LICENSE-COMMERCIAL.md.