loadbalance

package
v0.0.0-...-466e864 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package loadbalance provides the shared load-balancing schemes and a generic picker used by both nhp-relay (selecting which nhp-server instance to forward an HTTPS-bridged knock to) and nhp-agent (selecting which nhp-server instance in a cluster to send a knock to).

The scheme constants are part of the public configuration surface — they appear verbatim in operator-edited TOML files — so they live here rather than in any single endpoint's package.

Index

Constants

View Source
const DefaultScheme = SchemeWeightedRandom

DefaultScheme is what an empty / unset scheme normalises to. Weighted-random matches the documented intuition "spread requests proportionally to declared instance weights" without surprising operators who left the field blank.

Variables

This section is empty.

Functions

func NormalizeWeights

func NormalizeWeights[T Weighted](instances []T) int

NormalizeWeights returns the sum of weights with zero-weight instances counted as 1. Callers should precompute this once when building a Picker; the value stays constant for the picker's lifetime (instance churn requires a fresh Picker, just like a config reload).

Types

type Picker

type Picker[T Weighted] struct {
	// contains filtered or unexported fields
}

Picker selects one instance from a fixed slice according to a Scheme. Pick is safe for concurrent use; the round-robin cursor uses an atomic counter so handlers across goroutines don't contend on a mutex.

The slice referenced by Picker MUST be treated as immutable after construction — instances are picked by index, so reordering or resizing while picks are in flight would race with the counter. Build a fresh Picker on config reload instead.

func NewPicker

func NewPicker[T Weighted](scheme Scheme, instances []T) *Picker[T]

NewPicker constructs a Picker for the given instances. The scheme is normalised; pass loadbalance.Validate() upstream if you need to reject typos before reaching here. An unknown scheme is silently downgraded to the default (callers that pre-validated will never hit this fallback).

func (*Picker[T]) Instances

func (p *Picker[T]) Instances() []T

Instances returns the underlying slice. Callers must not mutate it — see the Picker doc-comment. Exposed only for read-only introspection (logs, /clusters endpoint, etc.).

func (*Picker[T]) Len

func (p *Picker[T]) Len() int

Len reports the number of instances in this picker. Useful for metrics ("cluster has N instances") and tests.

func (*Picker[T]) Pick

func (p *Picker[T]) Pick() (T, bool)

Pick returns one instance and true on success. When the picker has zero instances it returns the zero value and false — callers must branch on this rather than indexing the result, or empty clusters will silently appear to work.

func (*Picker[T]) PickByKey

func (p *Picker[T]) PickByKey(key string) (T, bool)

PickByKey returns an instance deterministically for the given key using FNV-64a hashing. Different keys MAY land on different instances; the same key always lands on the same instance as long as the instance slice is unchanged. Used by the relay to implement StickyInstance (source-IP-based session affinity).

func (*Picker[T]) Scheme

func (p *Picker[T]) Scheme() Scheme

Scheme returns the picker's scheme as normalised at construction.

type Scheme

type Scheme string

Scheme names a strategy for selecting an instance within a cluster. The string values are stable: they appear in operator-edited config files (relay.toml, agent's server.toml).

const (
	SchemeRandom         Scheme = "random"
	SchemeWeightedRandom Scheme = "weighted-random"
	SchemeRoundRobin     Scheme = "round-robin"
)

func (Scheme) Normalize

func (s Scheme) Normalize() Scheme

Normalize returns the scheme with the empty string replaced by DefaultScheme. Unknown schemes pass through unchanged — call Validate first to reject them.

func (Scheme) Validate

func (s Scheme) Validate() error

Validate rejects unknown scheme strings at config-load time. An empty string is accepted; callers should normalise it to DefaultScheme via Normalize before constructing a Picker.

type Weighted

type Weighted interface {
	Weight() int
}

Weighted is the contract an instance type must satisfy to be Picked. Implementations should return a non-negative integer; zero weight is treated as 1 in NormalizeWeights so an instance with weight 0 in the config still receives traffic.

Jump to

Keyboard shortcuts

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