Skip to main content

ScatterProxyRouter

Struct ScatterProxyRouter 

Source
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_for gives a clean, host-scoped view of throughput and health.

Each host is configured independently via its own ScatterProxyConfig, so you can tune sources, concurrency, timeouts, and logging per target.

§Example

use scatter_proxy::{ScatterProxyRouter, ScatterProxyConfig, DefaultClassifier};

let router = ScatterProxyRouter::new(
    [
        ("szse.cn",     ScatterProxyConfig { max_inflight: 20, ..Default::default() }),
        ("sse.com.cn",  ScatterProxyConfig { max_inflight: 10, ..Default::default() }),
        ("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

Source

pub async fn new( routes: impl IntoIterator<Item = (impl Into<String>, ScatterProxyConfig)>, classifier: impl BodyClassifier, ) -> Result<Self, ScatterProxyError>

Build a router with one independent ScatterProxy pool per host.

routes is an iterable of (hostname, config) pairs. Each host gets its own pool configured independently. If config.name is not set it defaults to the hostname so that metrics logs are prefixed correctly.

§Errors

Returns ScatterProxyError::Init if any host pool fails to initialise (e.g. the proxy source URL is unreachable and the list is empty).

Source

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.

Source

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.

Source

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.

Source

pub fn all_metrics(&self) -> HashMap<String, PoolMetrics>

Returns PoolMetrics snapshots for every registered host.

Source

pub fn hosts(&self) -> Vec<&str>

Returns the list of registered hostnames.

Source

pub async fn shutdown(self)

Gracefully shut down all host pools (persists state for each if configured).

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more