Documentation
¶
Overview ¶
Package sendrate enforces the per-agent fire-time submission budget — the durable, Postgres-backed counterpart of the acceptance-time in-memory send limit (internal/httpapi checkSendLimit, 60 submissions/min/agent). The outbound send worker (internal/outboundsend) reserves one slot immediately before each provider submission, so scheduled sends that accumulated as River jobs — and multi-replica deployments the in-memory limiter cannot coordinate — cannot burst past the advertised per-agent rate at the upstream provider.
Storage is one row per agent (migration 094) holding a sliding-window log of recent reservation timestamps. Reserve serializes on the row lock (SELECT ... FOR UPDATE), so the limit holds across replicas and concurrent workers without SKIP LOCKED or multi-statement races. All timestamps come from the DB server's clock (clock_timestamp() at statement execution — never the app's, and never the transaction-start time, which would stamp events early under lock contention) — app-clock skew never enters the window math.
Crash semantics: a slot is consumed at Reserve, BEFORE submission. A crash between Reserve and Deliver burns one slot without a submission — the provider sees FEWER sends than allowed (the fail-safe direction) — and River re-drives the job, which reserves again once the window has capacity. A crash between Deliver and MarkSent consumes no second slot: the provider_accepted_at evidence settles the row as sent on re-drive without re-submission. Rows self-prune on every Reserve (entries older than the window are dropped), so the limiter adds no janitor or cleanup obligation; a row is at most `limit` timestamps.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Decision ¶
Decision is the outcome of one reservation attempt. When Allowed is false, RetryAt is the earliest instant the agent's window frees a slot (the oldest kept event aging out).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store reserves fire-time submission slots against agent_send_rate_windows. window and limit are constructor-fixed (production wires 1 minute / 60 in cmd/e2a/main.go; tests use short windows).