throttle

package
v0.2.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package throttle provides leading-edge refractory throttle helpers used by controller components that bound their write rate to slow downstream systems (e.g. the Kubernetes API).

"Leading edge" means: the first work item submitted after the throttle is idle fires immediately. Subsequent items submitted within the refractory period are deferred — the helper signals via FiredCh() once the period expires so the caller can flush whatever has accumulated in its own pending queue.

The helper does NOT buffer work items. Callers retain ownership of pending state because that state often has caller-specific semantics (e.g. per-key coalescing, cleanup of replaced entries). The helper only owns the timing decision: "may I fire now?"

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type LeadingEdge

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

LeadingEdge enforces a leading-edge refractory throttle. It is safe for concurrent use; all methods take an internal mutex.

A zero-value LeadingEdge has interval == 0, meaning the gate is always open and ScheduleFlush is a no-op. Use New to configure the interval.

func New

func New(interval time.Duration) *LeadingEdge

New returns a LeadingEdge with the given refractory interval. If interval is zero or negative, Available always returns true and ScheduleFlush is a no-op — the throttle effectively passes everything through. The returned FiredCh has buffer 1 so timer signals never block.

func (*LeadingEdge) Available

func (t *LeadingEdge) Available() bool

Available reports whether the throttle gate is currently open. Returns true when the throttle is disabled (interval <= 0) or when the refractory period since the last MarkFired call has elapsed. Callers should fire immediately if true, else call ScheduleFlush to defer.

func (*LeadingEdge) FiredCh

func (t *LeadingEdge) FiredCh() <-chan struct{}

FiredCh returns the channel that signals "refractory period has expired — flush your pending queue now." The channel has buffer 1 so signals never block; consumers should treat each receive as "drain whatever is pending" rather than per-item delivery.

func (*LeadingEdge) MarkFired

func (t *LeadingEdge) MarkFired()

MarkFired records the current time as the most recent fire, opening a fresh refractory window. Callers should invoke this after a successful fire (typically inside the work that the worker just executed).

func (*LeadingEdge) ScheduleFlush

func (t *LeadingEdge) ScheduleFlush()

ScheduleFlush arms a one-shot timer that signals on FiredCh once the remaining refractory period expires. Multiple calls within the same refractory window are coalesced through the buffered FiredCh: only one signal lands, additional calls schedule extra timers whose signals are dropped (the worker only needs one wake-up to drain accumulated pending work).

If the throttle is disabled, ScheduleFlush is a no-op — callers should gate it behind Available() in that case anyway.

Jump to

Keyboard shortcuts

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