pub struct ScatterProxyRouter { /* private fields */ }Expand description
Routes proxied requests to per-host ScatterProxy instances.
Each registered host gets its own independent proxy pool, health tracker, and scheduler. Isolation means:
- A struggling host (all proxies in cooldown, low success rate) cannot starve tasks for other hosts.
- Proxy eviction is scoped per-host: a proxy that repeatedly fails for host A is marked dead only in A’s pool, while remaining available to B.
metrics_forgives a clean, host-scoped view of throughput and health.
Every pool is initialised with the full proxy list from config.sources
at construction time and then evolves independently.
§Example
use scatter_proxy::{ScatterProxyRouter, ScatterProxyConfig, DefaultClassifier};
let router = ScatterProxyRouter::new(
["szse.cn", "sse.com.cn", "cninfo.com.cn"],
ScatterProxyConfig::default(),
DefaultClassifier,
).await?;
let client = reqwest::Client::new();
let req = client.get("http://szse.cn/api/data").build().unwrap();
let handle = router.submit(req).await?;
// handle.await or handle.with_timeout(…) as usual
// Per-host observability
if let Some(m) = router.metrics_for("szse.cn") {
println!("szse success rate: {:.0}%", m.success_rate_1m * 100.0);
}
router.shutdown().await;Implementations§
Source§impl ScatterProxyRouter
impl ScatterProxyRouter
Sourcepub async fn new(
hosts: impl IntoIterator<Item = impl Into<String>>,
config: ScatterProxyConfig,
classifier: impl BodyClassifier,
) -> Result<Self, ScatterProxyError>
pub async fn new( hosts: impl IntoIterator<Item = impl Into<String>>, config: ScatterProxyConfig, classifier: impl BodyClassifier, ) -> Result<Self, ScatterProxyError>
Build a router with one independent ScatterProxy pool per host.
hosts is a list of bare hostnames (e.g. "szse.cn"). Requests
submitted to the router are matched against these names via
request.url().host_str().
The same config (cloned) and classifier (shared via Arc) are used
for every pool. If you need different parameters per host, build the
pools manually and route requests yourself.
§Errors
Returns ScatterProxyError::Init if any host pool fails to initialise
(e.g. the proxy source URL is unreachable and the list is empty).
Sourcepub async fn submit(
&self,
request: Request,
) -> Result<TaskHandle, ScatterProxyError>
pub async fn submit( &self, request: Request, ) -> Result<TaskHandle, ScatterProxyError>
Submit a request to the pool registered for its host.
Blocks until the pool has capacity, then returns a TaskHandle.
§Errors
Returns ScatterProxyError::UnknownHost if the request’s host is not
registered in this router.
Sourcepub fn try_submit(
&self,
request: Request,
) -> Result<TaskHandle, ScatterProxyError>
pub fn try_submit( &self, request: Request, ) -> Result<TaskHandle, ScatterProxyError>
Non-blocking submit variant.
§Errors
Returns ScatterProxyError::UnknownHost if the host is not registered,
or ScatterProxyError::PoolFull if the host’s pool is at capacity.
Sourcepub fn metrics_for(&self, host: &str) -> Option<PoolMetrics>
pub fn metrics_for(&self, host: &str) -> Option<PoolMetrics>
Returns a PoolMetrics snapshot for the given host.
Returns None if the host is not registered in this router.
Sourcepub fn all_metrics(&self) -> HashMap<String, PoolMetrics>
pub fn all_metrics(&self) -> HashMap<String, PoolMetrics>
Returns PoolMetrics snapshots for every registered host.