Skip to main content

Module fairness

Module fairness 

Source
Expand description

Per-actor admission quotas in front of the single writer.

The sequencer is one thread serving everyone, so the cost of one actor’s burst is paid by every other actor’s latency. Before this, nothing bounded that: an agent in a retry loop could put ten thousand ops in the channel and the human waiting behind them had no recourse but to wait.

A quota is a ceiling on how many of one actor’s ops can be awaiting a decision at once. That is the number the fairness bound is stated in: with a limit of Q, an op arriving from anyone else waits behind at most Q ops from any single other actor, whatever that actor is doing. Exceeding the quota is answered immediately with a rejection naming it — never by blocking, which would move the queue from the sequencer into the submitter’s thread and hide it.

§What “actor” means here, and what it does not

The key is Witness::key_id as claimed by the submission, taken without verifying the signature. It has to be: verification happens inside SubmitPolicy::check on the writer thread, which is the whole point of that design (authorization is evaluated at apply time), and verifying again at intake would double the cost of the one genuinely expensive step to answer a question about scheduling.

So this is fairness, not security, and the difference is worth being precise about:

  • An honest actor flooding is bounded. This is the case that actually happens, and the one the quota exists for.
  • An adversary claiming many identities evades the quota by spreading across them. Bounding that is the node’s rate limiter (--rate-limit-api), which counts requests rather than trusting what they claim.
  • An adversary claiming someone else’s key id can occupy that actor’s slots, which is a denial of service against one actor. It is bounded but not prevented: slots free the moment the writer decides, and a forged signature is rejected in one verification, so holding another actor’s quota costs sustained request volume — the rate limiter’s department again.

Naming a bucket is therefore not a claim about who anyone is. Nothing here is load-bearing for authorization, and nothing here may become so: the moment a decision about permission keys off this string, an unverified field has been promoted to an identity.

Structs§

Quotas
Shared per-actor in-flight counts. Cloneable; every clone refers to the same table.

Constants§

DEFAULT_QUOTA
Default ceiling on one actor’s ops awaiting a decision.
UNLIMITED
A limit meaning “do not enforce one”.