Class TransportRateLimits
- Namespace
- MailFathom.Infrastructure.Security.Transport
- Assembly
- MailFathom.Infrastructure.dll
How much traffic one process serves on a transport surface, and how fast one caller may ask for it.
public sealed class TransportRateLimits
- Inheritance
-
TransportRateLimits
- Inherited Members
Remarks
Two controls rather than one, because they bound different resources. The concurrency limit bounds what the process is doing at any instant — database connections, CPU, open response streams — and is shared by every caller of that surface, since a machine has one set of them. The token bucket bounds how often a single caller may ask, and is kept per caller, so a client that goes into a loop spends its own capacity rather than everyone's.
Nothing here names a surface. The same numbers describe the MCP endpoint and the administrative endpoint, and each surface is given an instance of its own, so what one endpoint is configured to permit says nothing about the other and neither endpoint's traffic reaches the other's limiters.
Both are in-process. Nothing here coordinates across instances, so a deployment running several processes enforces these numbers once per process rather than once in total, and none of it is protection against a distributed flood. The controls exist so that one misbehaving caller cannot exhaust the resources of the process it is talking to.
Queue limits default to zero throughout. A queued request is a request holding memory and a connection while it waits for capacity that is already gone, which turns an overload into a slower, larger overload; refusing it immediately tells the client to back off while the server is still healthy. A deployment that would rather absorb a short burst can configure a bounded queue, and bounded is the only shape available.
A caller queue costs more than it looks like it does, which is why RequestQueueLimit is bounded by MaxConcurrentRequests rather than only by its own range. The two limiters are acquired in order, so a request waiting for its caller's tokens has already taken a concurrency permit and holds it until the next replenishment — up to an hour away. Keeping the queue smaller than the permit count is what stops one caller out of capacity from parking every permit the surface has and refusing everyone else through a limit that is supposed to be its own.
Properties
- ConcurrencyQueueLimit
Gets how many requests wait for a concurrency slot before the rest are refused.
- Default
Gets the limits a deployment that configures nothing runs under.
- MaxConcurrentRequests
Gets how many requests the process serves at once on this surface, across every caller.
- ReplenishmentPeriod
Gets how often a caller's spent capacity is restored.
- RequestQueueLimit
Gets how many of one caller's requests wait for capacity before the rest are refused.
- TokenCapacity
Gets the largest burst one caller may spend at once.
- TokensPerReplenishmentPeriod
Gets how much of that burst one caller gets back each ReplenishmentPeriod.
Methods
- Create(int, int, int, int, TimeSpan, int)
Creates the limits a transport surface runs under.