pub struct RequestLimits { /* private fields */ }Expand description
Spaces requests evenly: at most per_second a second across every job,
the browser’s and the watch list’s alike. Each caller takes the next free
slot and sleeps until it; the lock is held only to take the slot, never
across the sleep. It also remembers when recent requests went, for the
request-rate meter.
It also holds each device’s gate: a one-permit semaphore that a request
to the device holds from before its slot until its answer (see
turn). The std mutex around the map is held only to look
a gate up, never across an await.
Implementations§
Source§impl RequestLimits
impl RequestLimits
Sourcepub fn with_network_rates(
self,
default: u32,
rates: impl IntoIterator<Item = (u16, u32)>,
) -> Self
pub fn with_network_rates( self, default: u32, rates: impl IntoIterator<Item = (u16, u32)>, ) -> Self
These limits, with a rate per network as well: default requests a
second for any network (0 for no cap of its own), and rates for
the networks named, network 0 being the local one. The network
number doesn’t say what link lies behind a router, so a slow MS/TP
trunk has to be named.
Sourcepub fn paces_networks(&self) -> bool
pub fn paces_networks(&self) -> bool
True when requests are spaced per network too, so a request has to
say which network its device is on (turn_on).
Sourcepub fn gate(&self, device: u32) -> Arc<Semaphore> ⓘ
pub fn gate(&self, device: u32) -> Arc<Semaphore> ⓘ
device’s gate: one permit, held by whichever request to it is
outstanding. A managed COV subscription takes it for its renewals.
Sourcepub async fn turn(&self, device: u32) -> Turn
pub async fn turn(&self, device: u32) -> Turn
Wait for device’s gate, then for this request’s slot. The turn
holds the gate until it is dropped, so keep it for exactly the one
request: a job that takes a second turn while holding the first
waits on itself.
The gate comes first so a request queued behind another one to the same device holds no slot meanwhile. The wait is cancel-safe: a dropped wait leaves the semaphore’s queue.
Sourcepub async fn slot(&self, network: Option<u16>)
pub async fn slot(&self, network: Option<u16>)
A slot for one more request while the caller already holds its
device’s turn, as a log page’s later requests do: the caller’s
token, then network’s rate and the global rate, charged as a
request of its own.
Sourcepub async fn wait_device_free(&self, device: u32)
pub async fn wait_device_free(&self, device: u32)
Wait until device’s gate is free and a request could go at once,
taking neither; see wait_free for why.
Sourcepub async fn wait_free(&self)
pub async fn wait_free(&self)
Wait until a request could go at once, without reserving a slot: a caller that decides only then what to send (the name reads) spends no slot on work withdrawn while it waited.
That holds only while the caller doesn’t await between this and its
acquire: deciding what to send must be
synchronous (the TUI’s name reads take their batch under a std
mutex). An await there lets other jobs book the free slot first, and
the caller’s request then waits for a later one, for rows that may
have been withdrawn meanwhile.