backpressure

package
v0.22.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package backpressure controls Store dispatch using feedback from real work. All ready Store executions share one bounded FIFO. The controller owns no background goroutine, dependency probe or retry policy.

Index

Constants

View Source
const DefaultMaxConcurrent = 64

Variables

View Source
var ErrQueueFull = status.Error(codes.ResourceExhausted, "Store waiting capacity is full")

ErrQueueFull proves that admission did not start backend work.

Functions

func Observe

func Observe(backend storage.Storage, controller *Controller) storage.Storage

Observe never waits for admission, changes results or retries a call. Keep the original Storage separately for ownership/Close and health checks.

Types

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

func New

func New(opts Options) (*Controller, error)

func (*Controller) Acquire

func (c *Controller) Acquire(ctx context.Context) (*Permit, error)

Acquire waits only at the already bounded Kafka processing loop. Engine requests use Admit or enqueue a batch Ticket, never this unqueued wait path.

func (*Controller) Admit

func (c *Controller) Admit(ctx context.Context, requestBytes int) (context.Context, *Permit, error)

Admit reuses an execution's permit, or waits in the same FIFO as ready batches. Only the caller's original context ends admission waiting.

func (*Controller) Collect

func (c *Controller) Collect(ch chan<- prometheus.Metric)

func (*Controller) Describe

func (c *Controller) Describe(ch chan<- *prometheus.Desc)

func (*Controller) Enqueue added in v0.22.0

func (c *Controller) Enqueue(reservations []*Reservation) (*Ticket, <-chan struct{})

Enqueue transfers existing byte reservations into one FIFO task. A full task queue leaves ownership with the producer; changed wakes a batcher to retry. It does not count such retries as rejected business requests.

func (*Controller) Ready

func (c *Controller) Ready() (bool, <-chan struct{}, time.Duration)

Ready lets startup and Worker prefetch observe capacity without reserving a slot or inventing demand. Engine execution tickets are polled separately.

func (*Controller) Reserve added in v0.22.0

func (c *Controller) Reserve(requestBytes int) (*Reservation, error)

func (*Controller) TryAcquire

func (c *Controller) TryAcquire() (*Permit, <-chan struct{}, time.Duration)

TryAcquire is used by the bounded Worker loop; it cannot bypass queued tasks. Engine dispatchers enqueue a Ticket instead. On failure, changed and delay describe when to retry; delay == 0 means only a completion or another state change can free capacity.

func (*Controller) Wait

func (c *Controller) Wait(ctx context.Context) error

Wait observes available capacity without reserving a permit. Engine uses it before serving; Worker uses it before polling so backlog stays in Kafka while consumer group heartbeats and rebalance callbacks continue.

type Options

type Options struct {
	Store string
	Role  string
	// MaxConcurrent is a local resource ceiling, not an estimate of DB capacity.
	MaxConcurrent  int
	MaxQueuedTasks int
	MaxQueuedBytes int
}

type Permit

type Permit struct {
	// contains filtered or unexported fields
}

Permit reserves one sequential execution, including its existing conflict retries. Reducing the window never revokes already admitted executions.

func (*Permit) Context

func (p *Permit) Context(ctx context.Context) context.Context

func (*Permit) Release

func (p *Permit) Release()

type Reservation added in v0.22.0

type Reservation struct {
	// contains filtered or unexported fields
}

Reservation charges retained request bytes across collection and admission. Moving a request into a batch never releases and reacquires its budget.

func (*Reservation) Release added in v0.22.0

func (r *Reservation) Release()

type Ticket added in v0.22.0

type Ticket struct {
	// contains filtered or unexported fields
}

Ticket is one ready execution, whether it contains one RPC or a whole batch. Polling it never blocks a batcher's cancellation/completion event loop.

func (*Ticket) Cancel added in v0.22.0

func (t *Ticket) Cancel()

func (*Ticket) Poll added in v0.22.0

func (t *Ticket) Poll() (*Permit, <-chan struct{}, time.Duration)

Poll grants a permit only to the FIFO head. Timers only wake that head; they neither execute work nor impose an admission deadline.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL