Documentation
¶
Overview ¶
Package limits owns the request-rate and consumption vocabulary that bounds what a holder may spend. Both a gateway API key and an account hold limits, so the vocabulary lives here rather than inside either owner.
Index ¶
- Constants
- Variables
- func ContextWithAllowance(ctx context.Context, allowance Allowance) context.Context
- func ValidInterval(interval string) bool
- type AdmissionRule
- type Allowance
- type Budget
- type BudgetHolder
- type BudgetPolicy
- type BudgetPolicyReader
- type BudgetRule
- type Dimension
- type LevelRule
- type Limits
- type OutstandingJobsRule
- type RequestLimit
- type RequestRule
- type Scope
- type StoredBytesRule
- type TeamBudget
Constants ¶
const ( // IntervalDay selects the fixed UTC day window. IntervalDay = "day" // IntervalWeek selects the fixed UTC ISO week window. IntervalWeek = "week" // IntervalMonth selects the fixed UTC month window. IntervalMonth = "month" )
Budget interval names. The values match the fixed UTC aggregation intervals that the usage seam maintains, so a stored budget interval reads one exact aggregate window.
const CorrectionHorizon = 90 * 24 * time.Hour
CorrectionHorizon bounds new corrections from the original charge settlement. It never expires unresolved reservations or accepted audit evidence.
const OutstandingJobsPrefix = "limits:v1:outstanding_jobs:"
OutstandingJobsPrefix is the retained account-count namespace. The jobslots repository owns its versioned format and durable claim records.
Variables ¶
var ( // ErrInvalidRequestLimit reports a non-positive request limit. ErrInvalidRequestLimit = errors.New("request limit must be positive") // ErrInvalidRequestWindow reports a non-positive request window. ErrInvalidRequestWindow = errors.New("request window seconds must be positive") // ErrInvalidBudgetLimit reports a non-positive budget limit. ErrInvalidBudgetLimit = errors.New("budget limit must be positive") // ErrInvalidBudgetInterval reports an unknown budget interval. ErrInvalidBudgetInterval = errors.New("budget interval must be day, week, or month") // ErrInvalidStoredBytes reports a non-positive stored byte bound. ErrInvalidStoredBytes = errors.New("stored bytes limit must be positive") // ErrInvalidOutstandingJobs reports a non-positive outstanding job bound. ErrInvalidOutstandingJobs = errors.New("outstanding jobs limit must be positive") )
var ( // ErrCounterRequired reports a meter built without durable storage. ErrCounterRequired = errors.New("level counter is required") // ErrInvalidHolder reports an empty holder identity. ErrInvalidHolder = errors.New("level holder is required") )
var ErrBudgetPolicyUnknown = errors.New("budget policy is unknown")
ErrBudgetPolicyUnknown refuses to infer absent budgets from missing policy.
var ErrCorrectionExpired = errors.New("the settled-charge correction deadline passed")
ErrCorrectionExpired refuses a new correction after its original deadline.
var ErrOutstandingJobsRecoveryRequired = errors.New("outstanding job ownership requires recovery")
ErrOutstandingJobsRecoveryRequired refuses admission without known ownership.
var ErrSpendLimitExceeded = errors.New("spend limit exceeded")
ErrSpendLimitExceeded reports work a holder's spend budget cannot pay for.
var ErrTooManyOutstandingJobs = errors.New("outstanding job limit exceeded")
ErrTooManyOutstandingJobs refuses work beyond the account's current bound.
Functions ¶
func ContextWithAllowance ¶
ContextWithAllowance carries one holder's remaining spend into the request.
func ValidInterval ¶
ValidInterval reports whether interval names a supported budget window.
Types ¶
type AdmissionRule ¶ added in v1.3.0
type AdmissionRule struct {
Scope Scope
Holder string
Revision uint64
Dimension Dimension
Budget Budget
}
AdmissionRule is one applicable meter and its admitted policy revision.
type Allowance ¶
type Allowance struct {
// NanoUSD is what remains in the window. It is meaningful only when
// Bounded is true.
NanoUSD int64
// Bounded reports that a spend budget applies to this holder.
Bounded bool
}
Allowance is what one holder may still spend in its current budget window, in integer nano-USD.
An unbounded allowance is the normal case: most deployments set no spend budget at all, and a holder without one is not metered against anything. Bounded says which of the two a zero means, because a holder with nothing left and a holder with no budget are opposite answers.
func AllowanceFromContext ¶
AllowanceFromContext reads the remaining spend the budget gate recorded.
A request that never passed the gate reads as unbounded. That is the honest answer rather than a permissive default: no budget was found, so no budget refuses anything.
func (Allowance) Covers ¶
Covers reports whether the allowance pays for work priced at nanoUSD.
It refuses the work that crosses the bound rather than the work after it. A caller at the door is refused on a window already spent, which lets the crossing request through; here the price is known before the money is spent, so refusing first is both possible and cheaper for the account.
type Budget ¶
type Budget struct {
Limit int64 `json:"limit"`
Interval string `json:"interval"`
// HistoryID is server-owned accounting continuity. Missing history remains unknown.
HistoryID string `json:"history_id,omitempty"`
}
Budget bounds one consumption dimension inside one fixed UTC interval.
type BudgetHolder ¶ added in v1.3.0
BudgetHolder contains the consumption policy of one verified holder revision. Nil budgets mean confirmed absence only after the caller verifies that record.
type BudgetPolicy ¶ added in v1.3.0
type BudgetPolicy struct {
// contains filtered or unexported fields
}
BudgetPolicy retains immutable account, key, and optional team consumption policy. The authorization owner constructs it once when accepting the complete bundle.
func NewBudgetPolicy ¶ added in v1.3.0
func NewBudgetPolicy(account, key BudgetHolder, team *BudgetHolder) (*BudgetPolicy, error)
NewBudgetPolicy copies all limits from verified policy records. A nil team confirms that the key has no team dependency.
func (*BudgetPolicy) Identity ¶ added in v1.3.0
func (p *BudgetPolicy) Identity() (account, key, team string)
Identity returns the original meter populations, including an absent team.
func (*BudgetPolicy) Rule ¶ added in v1.3.0
func (p *BudgetPolicy) Rule(index int) (AdmissionRule, bool)
Rule returns a value copy of one meter without copying unrelated account metadata.
func (*BudgetPolicy) RuleCount ¶ added in v1.3.0
func (p *BudgetPolicy) RuleCount() int
RuleCount returns how many required meters apply. Zero confirms no budgets.
type BudgetPolicyReader ¶ added in v1.3.0
type BudgetPolicyReader interface {
BudgetPolicy() (*BudgetPolicy, error)
}
BudgetPolicyReader checks the original permission before returning its policy. Child calls inherit this reader. They cannot invent an unlimited default.
type BudgetRule ¶
BudgetRule is one consumption meter a request must satisfy.
func BudgetRules ¶
func BudgetRules(accountLimits, keyLimits *Limits, dimension Dimension) []BudgetRule
BudgetRules returns every consumption meter one request must satisfy for one dimension, account before key.
func TeamBudgetRule ¶ added in v1.2.0
func TeamBudgetRule(budget *TeamBudget) (BudgetRule, bool)
TeamBudgetRule projects a stored team budget into the consumption rule the enforcement path runs beside the account and key rules. It reports false when the team sets no budget.
type Limits ¶
type Limits struct {
// Requests overrides the global request window for this holder.
Requests *RequestLimit `json:"requests,omitempty"`
// Spend bounds integer nano-USD spend inside one fixed UTC interval.
Spend *Budget `json:"spend,omitempty"`
// Tokens bounds total token consumption inside one fixed UTC interval.
Tokens *Budget `json:"tokens,omitempty"`
// StoredBytes bounds how many bytes this holder keeps in file storage at
// one time. It is a level rather than a rate, so no interval resets it: a
// write raises the total and a delete lowers it.
StoredBytes *int64 `json:"stored_bytes,omitempty"`
// OutstandingJobs bounds how many jobs this holder may have running at
// one time. Like StoredBytes it is a level rather than a rate, and unlike
// every other limit here it meters work that has not finished: a submitted
// job is a spend commitment this gateway cannot read yet.
OutstandingJobs *int64 `json:"outstanding_jobs,omitempty"`
}
Limits carries the request-rate override and the consumption budgets of one holder. A nil field leaves that dimension unlimited by this holder.
func (*Limits) WithBudgetHistory ¶ added in v1.3.0
WithBudgetHistory ignores caller-supplied history identifiers and preserves continuity only for a budget that keeps its original interval.
type OutstandingJobsRule ¶
type OutstandingJobsRule = LevelRule
OutstandingJobsRule is one outstanding job bound a submission must satisfy.
func TightestOutstandingJobs ¶
func TightestOutstandingJobs(accountLimits, keyLimits *Limits) (OutstandingJobsRule, bool)
TightestOutstandingJobs reports the outstanding job bound a submission must satisfy, and whether one applies at all.
It resolves the same way stored bytes do, and for the same reason. A job belongs to an account, so both bounds read one counter and the smaller of them satisfies the larger. A key bound is an operator asking that this key not fill the account's queue on its own.
type RequestLimit ¶
RequestLimit is one request-rate override.
type RequestRule ¶
type RequestRule struct {
Scope Scope
Limit RequestLimit
}
RequestRule is one request-rate meter a request must satisfy.
func RequestRules ¶
func RequestRules(accountLimits, keyLimits *Limits, deploymentDefault *RequestLimit) []RequestRule
RequestRules returns every request-rate meter one request must satisfy, account before key. deploymentDefault is the gateway's global window; it applies at key scope only when the key sets no request limit of its own, because an explicit key limit is admin intent about that key. Pass nil when the deployment has no global window.
type Scope ¶
type Scope string
Scope names the holder that set a limit.
const ScopeTeam Scope = "team"
ScopeTeam is a team-wide limit. It meters every key attributed to the team.
type StoredBytesRule ¶
type StoredBytesRule = LevelRule
StoredBytesRule is one stored byte bound an upload must satisfy.
func TightestStoredBytes ¶
func TightestStoredBytes(accountLimits, keyLimits *Limits) (StoredBytesRule, bool)
TightestStoredBytes reports the stored byte bound an upload must satisfy, and whether one applies at all.
Stored bytes resolve to the smaller of the two, which is the opposite of what RequestRules does above, and for a reason the shapes of the two meters give. A request rate meters two different populations, so both meters have to run. Stored bytes meter one: a file belongs to an account, and a key holds no bytes of its own. Both bounds therefore read the same counter, and running the smaller one satisfies the larger by arithmetic.
A key bound is an operator asking that this key not push the account past a tighter number than the account's own. The returned scope names which holder set the bound, so a refusal can name the owner an operator has to talk to.
type TeamBudget ¶ added in v1.2.0
type TeamBudget struct {
Limit int64 `json:"limit"`
Interval string `json:"interval"`
// HistoryID identifies continuous accounting independently of policy revisions.
HistoryID string `json:"history_id,omitempty"`
}
TeamBudget bounds a team's consumption of one dimension inside one fixed UTC interval. It is a distinct named type rather than a bare Budget so the identity seam can carry it without importing the meaning of every other limit dimension a Limits carrier holds.
func (*TeamBudget) Clone ¶ added in v1.2.0
func (b *TeamBudget) Clone() *TeamBudget
Clone returns a deep copy of the team budget.
func (*TeamBudget) Validate ¶ added in v1.2.0
func (b *TeamBudget) Validate() error
Validate checks the team budget invariants.
func (*TeamBudget) WithBudgetHistory ¶ added in v1.3.0
func (b *TeamBudget) WithBudgetHistory(previous *TeamBudget) *TeamBudget
WithBudgetHistory gives team policies the same continuity rules as other holders.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package admission owns permission, capacity, and settlement for paid attempts.
|
Package admission owns permission, capacity, and settlement for paid attempts. |
|
Package jobslots owns durable outstanding-work claims for videos and batches.
|
Package jobslots owns durable outstanding-work claims for videos and batches. |
|
Package reservation owns durable budget capacity for individual provider attempts.
|
Package reservation owns durable budget capacity for individual provider attempts. |
|
Package storedbytes owns durable byte claims and account capacity.
|
Package storedbytes owns durable byte claims and account capacity. |