Loading...
Searching...
No Matches
ATAS.DataFeedsCore.RequestLimiter Class Reference

Token bucket bounding the rate of requests sent to a broker: Capacity is the largest burst allowed at once, RefillPerSecond the sustained ceiling. The bucket starts full, refills continuously (fractional tokens) and never accumulates more than Capacity. Refill is computed from a TimeProvider on demand, so the limiter owns no timer and no background thread and is fully testable with a fake time provider. More...

Public Member Functions

 RequestLimiter (int capacity, double refillPerSecond, TimeProvider? timeProvider=null)
 Creates a full bucket.
 
bool TryTake (int tokens=1)
 Takes tokens tokens if the bucket holds enough, atomically.
 
TimeSpan GetWaitTime (int tokens=1)
 How long to wait before TryTake of the same amount can succeed, assuming nobody else takes tokens meanwhile. Takes nothing itself.
 
async Task WaitAsync (int tokens=1, CancellationToken cancellationToken=default)
 Waits until tokens tokens could be taken and takes them. Not fair - see the remarks on the class.
 
void Reset ()
 Fills the bucket again, dropping the accumulated debt. Used when the state the limiter protects is gone (connector disconnect), not as a way around the budget.
 

Properties

int Capacity [get]
 Bucket size: the number of tokens available at once after an idle period, and the largest amount a single TryTake may ask for.
 
double RefillPerSecond [get]
 Tokens added per second, fractional. Together with Capacity it defines the sustained request ceiling.
 
double AvailableTokens [get]
 Tokens available at this moment, refill included. Fractional and immediately stale; meant for tests and telemetry, not for deciding whether a request may be sent - use TryTake for that.
 

Detailed Description

Token bucket bounding the rate of requests sent to a broker: Capacity is the largest burst allowed at once, RefillPerSecond the sustained ceiling. The bucket starts full, refills continuously (fractional tokens) and never accumulates more than Capacity. Refill is computed from a TimeProvider on demand, so the limiter owns no timer and no background thread and is fully testable with a fake time provider.

Every member is thread-safe. WaitAsync is a plain retry loop and does not queue its callers: waiters are not served in arrival order and a caller asking for many tokens can be overtaken by a caller asking for one. That is intentional - the only waiter is the single option subscription pump of one connector (PLAT-5011), and a fair queue would be dead weight; the connector-level OptionRequestGuard only calls TryTake. A future consumer with several concurrent waiters must not rely on fairness here.

Constructor & Destructor Documentation

◆ RequestLimiter()

ATAS.DataFeedsCore.RequestLimiter.RequestLimiter ( int  capacity,
double  refillPerSecond,
TimeProvider?  timeProvider = null 
)

Creates a full bucket.

Parameters
capacityBucket size in tokens, at least 1.
refillPerSecondTokens added per second, greater than 0.
timeProviderTime source; TimeProvider.System when omitted.

Member Function Documentation

◆ GetWaitTime()

TimeSpan ATAS.DataFeedsCore.RequestLimiter.GetWaitTime ( int  tokens = 1)

How long to wait before TryTake of the same amount can succeed, assuming nobody else takes tokens meanwhile. Takes nothing itself.

Parameters
tokensTokens to account for, within [1; Capacity].
Returns
TimeSpan.Zero when the bucket already holds enough.

◆ Reset()

void ATAS.DataFeedsCore.RequestLimiter.Reset ( )

Fills the bucket again, dropping the accumulated debt. Used when the state the limiter protects is gone (connector disconnect), not as a way around the budget.

◆ TryTake()

bool ATAS.DataFeedsCore.RequestLimiter.TryTake ( int  tokens = 1)

Takes tokens tokens if the bucket holds enough, atomically.

Parameters
tokensTokens to take, within [1; Capacity].
Returns
true when the tokens were taken, false when the bucket is short.

◆ WaitAsync()

async Task ATAS.DataFeedsCore.RequestLimiter.WaitAsync ( int  tokens = 1,
CancellationToken  cancellationToken = default 
)

Waits until tokens tokens could be taken and takes them. Not fair - see the remarks on the class.

Parameters
tokensTokens to take, within [1; Capacity].
cancellationTokenCancels the wait; no tokens are taken then.

Property Documentation

◆ AvailableTokens

double ATAS.DataFeedsCore.RequestLimiter.AvailableTokens
get

Tokens available at this moment, refill included. Fractional and immediately stale; meant for tests and telemetry, not for deciding whether a request may be sent - use TryTake for that.

◆ Capacity

int ATAS.DataFeedsCore.RequestLimiter.Capacity
get

Bucket size: the number of tokens available at once after an idle period, and the largest amount a single TryTake may ask for.

◆ RefillPerSecond

double ATAS.DataFeedsCore.RequestLimiter.RefillPerSecond
get

Tokens added per second, fractional. Together with Capacity it defines the sustained request ceiling.


The documentation for this class was generated from the following file: