Help us shape the future of Go! Take the 2026 Go Developer Survey

rate

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2025 License: MPL-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package rate implements server-side RPC rate limiting.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrRetryElsewhere indicates that the operation was not allowed because the
	// rate limit was exhausted, but may succeed on a different server.
	//
	// Results in a RESOURCE_EXHAUSTED or "429 Too Many Requests" response.
	ErrRetryElsewhere = errors.New("rate limit exceeded, try again later or against a different server")

	// ErrRetryLater indicates that the operation was not allowed because the rate
	// limit was exhausted, and trying a different server won't help (e.g. because
	// the operation can only be performed on the leader).
	//
	// Results in an UNAVAILABLE or "503 Service Unavailable" response.
	ErrRetryLater = errors.New("rate limit exceeded for operation that can only be performed by the leader, try again later")
)
View Source
var Counters = []prometheus.CounterDefinition{
	{
		Name: []string{"rpc", "rate_limit", "exceeded"},
		Help: "Increments whenever an RPC is over a configured rate limit. Note: in permissive mode, the RPC will have still been allowed to proceed.",
	},
	{
		Name: []string{"rpc", "rate_limit", "log_dropped"},
		Help: "Increments whenever a log that is emitted because an RPC exceeded a rate limit gets dropped because the output buffer is full.",
	},
}
View Source
var ModeFromName = func() map[string]Mode {
	vals := map[string]Mode{
		"": ModeDisabled,
	}
	for k, v := range modeToName {
		vals[v] = k
	}
	return vals
}()

Functions

This section is empty.

Types

type GlobalLimitConfig

type GlobalLimitConfig struct {
	Mode Mode
	ReadWriteConfig
}

type Handler

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

Handler enforces rate limits for incoming RPCs.

func NewHandler

func NewHandler(cfg HandlerConfig, logger hclog.Logger) *Handler

NewHandler creates a new RPC rate limit handler.

func NewHandlerWithLimiter

func NewHandlerWithLimiter(
	cfg HandlerConfig,
	limiter multilimiter.RateLimiter,
	logger hclog.Logger) *Handler

func (*Handler) Allow

func (h *Handler) Allow(op Operation) error

Allow returns an error if the given operation is not allowed to proceed because of an exhausted rate-limit.

func (*Handler) Register

func (h *Handler) Register(serversStatusProvider ServersStatusProvider)

func (*Handler) Run

func (h *Handler) Run(ctx context.Context)

Run the limiter cleanup routine until the given context is canceled.

Note: this starts a goroutine.

func (*Handler) UpdateConfig

func (h *Handler) UpdateConfig(cfg HandlerConfig)

func (*Handler) UpdateIPConfig

func (h *Handler) UpdateIPConfig(cfg IPLimitConfig)

type HandlerConfig

type HandlerConfig struct {
	multilimiter.Config

	GlobalLimitConfig GlobalLimitConfig
}

type IPLimitConfig

type IPLimitConfig struct{}

type MockRequestLimitsHandler

type MockRequestLimitsHandler struct {
	mock.Mock
}

MockRequestLimitsHandler is an autogenerated mock type for the RequestLimitsHandler type

func NewMockRequestLimitsHandler

func NewMockRequestLimitsHandler(t mockConstructorTestingTNewMockRequestLimitsHandler) *MockRequestLimitsHandler

NewMockRequestLimitsHandler creates a new instance of MockRequestLimitsHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.

func (*MockRequestLimitsHandler) Allow

Allow provides a mock function with given fields: op

func (*MockRequestLimitsHandler) Register

func (_m *MockRequestLimitsHandler) Register(serversStatusProvider ServersStatusProvider)

Register provides a mock function with given fields: serversStatusProvider

func (*MockRequestLimitsHandler) Run

Run provides a mock function with given fields: ctx

func (*MockRequestLimitsHandler) UpdateConfig

func (_m *MockRequestLimitsHandler) UpdateConfig(cfg HandlerConfig)

UpdateConfig provides a mock function with given fields: cfg

func (*MockRequestLimitsHandler) UpdateIPConfig

func (_m *MockRequestLimitsHandler) UpdateIPConfig(cfg IPLimitConfig)

UpdateIPConfig provides a mock function with given fields: cfg

type Mode

type Mode int

Mode determines the action that will be taken when a rate limit has been exhausted (e.g. log and allow, or reject).

const (
	// ModeDisabled causes rate limiting to be bypassed.
	ModeDisabled Mode = iota

	// ModePermissive causes the handler to log the rate-limited operation but
	// still allow it to proceed.
	ModePermissive

	// ModeEnforcing causes the handler to reject the rate-limited operation.
	ModeEnforcing
)

func RequestLimitsModeFromName

func RequestLimitsModeFromName(name string) (Mode, bool)

RequestLimitsModeFromName will unmarshal the string form of a configMode.

func RequestLimitsModeFromNameWithDefault

func RequestLimitsModeFromNameWithDefault(name string) Mode

RequestLimitsModeFromNameWithDefault will unmarshal the string form of a configMode.

func (Mode) String

func (m Mode) String() string

type Operation

type Operation struct {
	// Name of the RPC endpoint (e.g. "Foo.Bar" for net/rpc and "/foo.service/Bar" for gRPC).
	Name string

	// SourceAddr is the client's (or forwarding server's) IP address.
	SourceAddr net.Addr

	// Type of operation to be performed (e.g. read or write).
	Type OperationType

	Category OperationCategory
}

Operation the client is attempting to perform.

type OperationCategory

type OperationCategory string
const (
	OperationCategoryACL             OperationCategory = "ACL"
	OperationCategoryCatalog         OperationCategory = "Catalog"
	OperationCategoryConfigEntry     OperationCategory = "ConfigEntry"
	OperationCategoryConnectCA       OperationCategory = "ConnectCA"
	OperationCategoryCoordinate      OperationCategory = "Coordinate"
	OperationCategoryDiscoveryChain  OperationCategory = "DiscoveryChain"
	OperationCategoryServerDiscovery OperationCategory = "ServerDiscovery"
	OperationCategoryHealth          OperationCategory = "Health"
	OperationCategoryIntention       OperationCategory = "Intention"
	OperationCategoryKV              OperationCategory = "KV"
	OperationCategoryPreparedQuery   OperationCategory = "PreparedQuery"
	OperationCategorySession         OperationCategory = "Session"
	OperationCategoryStatus          OperationCategory = "Status" // not limited
	OperationCategoryTxn             OperationCategory = "Txn"
	OperationCategoryAutoConfig      OperationCategory = "AutoConfig"
	OperationCategoryFederationState OperationCategory = "FederationState"
	OperationCategoryInternal        OperationCategory = "Internal"
	OperationCategoryOperator        OperationCategory = "Operator" // not limited
	OperationCategoryPeerStream      OperationCategory = "PeerStream"
	OperationCategoryPeering         OperationCategory = "Peering"
	OperationCategoryPartition       OperationCategory = "Tenancy"
	OperationCategoryDataPlane       OperationCategory = "DataPlane"
	OperationCategoryDNS             OperationCategory = "DNS"
	OperationCategorySubscribe       OperationCategory = "Subscribe"
	OperationCategoryResource        OperationCategory = "Resource"
)

type OperationSpec

type OperationSpec struct {
	Type     OperationType
	Category OperationCategory
}

type OperationType

type OperationType int

OperationType is the type of operation the client is attempting to perform.

const (
	// OperationTypeRead represents a read operation.
	OperationTypeRead OperationType = iota

	// OperationTypeWrite represents a write operation.
	OperationTypeWrite

	// OperationTypeExempt represents an operation that is exempt from rate-limiting.
	OperationTypeExempt
)

type ReadWriteConfig

type ReadWriteConfig struct {
	// WriteConfig configures the global rate limiter for write operations.
	WriteConfig multilimiter.LimiterConfig

	// ReadConfig configures the global rate limiter for read operations.
	ReadConfig multilimiter.LimiterConfig
}

type RequestLimitsHandler

type RequestLimitsHandler interface {
	Run(ctx context.Context)
	Allow(op Operation) error
	UpdateConfig(cfg HandlerConfig)
	UpdateIPConfig(cfg IPLimitConfig)
	Register(serversStatusProvider ServersStatusProvider)
}

func NullRequestLimitsHandler

func NullRequestLimitsHandler() RequestLimitsHandler

NullRequestLimitsHandler returns a RequestLimitsHandler that allows every operation.

type ServersStatusProvider

type ServersStatusProvider interface {
	// IsLeader is used to determine whether the operation is being performed
	// against the cluster leader, such that if it can _only_ be performed by
	// the leader (e.g. write operations) we don't tell clients to retry against
	// a different server.
	IsLeader() bool
	IsServer(addr string) bool
}

Jump to

Keyboard shortcuts

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