Documentation
¶
Overview ¶
SPDX-License-Identifier: MIT Package apibudget accounts for and bounds the provider HTTP requests a query consumes. It works at the transport layer rather than at call sites, which gives exact counts (including pagination and retries), covers every existing provider path without touching one of them, and puts rate-header capture in a single place.
The mechanism is internal; only its data shape (model.CostReport) is public, keeping the public API minimal.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrBudgetExceeded = errors.New("api request budget exceeded")
ErrBudgetExceeded is returned instead of dispatching a request once the configured ceiling has been consumed. Callers branch on it with errors.Is to convert a budget stop into a partial result plus a disclosure rather than a failure.
It surfaces through http.Client wrapped in a *url.Error, which unwraps, so errors.Is keeps working end to end.
Functions ¶
func Unmetered ¶
Unmetered marks requests made with the returned context as not counting against the ceiling.
It exists for endpoints the provider itself does not charge — GitHub's /rate_limit is the motivating case. Charging a free pre-flight check against the user's request budget would both misstate what the query cost and make a small explicit ceiling unusable, since the check would consume it before any evidence could be gathered.
Rate headers from an unmetered response are still recorded: the observation is exactly what the request was for.
Types ¶
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport counts every request it dispatches, refuses to dispatch beyond a ceiling, and records the rate-limit headers from every response.
A ceiling of 0 disables the cap but keeps counting: accounting is never optional, only enforcement is.
func NewTransport ¶
func NewTransport(next http.RoundTripper, ceiling int) *Transport
NewTransport wraps next, counting and bounding the requests that pass through it. A nil next uses http.DefaultTransport. ceiling <= 0 means uncapped.
func (*Transport) Remaining ¶
Remaining reports how many more requests the ceiling permits. It returns math.MaxInt when uncapped.
This is the check-before-dispatch accessor: a concurrent fan-out asks how much it can afford and dispatches only a batch it can fully pay for, rather than firing requests and letting the losers fail. Without that, which requests won the race would decide which commits got enriched, and the same query could return different results run to run.
func (*Transport) Report ¶
func (t *Transport) Report() model.CostReport
Report snapshots consumption and the latest quota observation. It is safe to call at any point, including on an early-return path — a query that stopped early must still report what it spent.