throttling

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2022 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewThrottledListener

func NewThrottledListener(listener net.Listener, maxConnsPerSec float64) net.Listener

Wraps [listener] and returns a net.Listener that will accept at most [maxConnsPerSec] connections per second. [maxConnsPerSec] must be non-negative.

Types

type BandwidthThrottler

type BandwidthThrottler interface {
	// Blocks until [nodeID] can read a message of size [msgSize].
	// AddNode([nodeID], ...) must have been called since
	// the last time RemoveNode([nodeID]) was called, if any.
	// It's safe for multiple goroutines to concurrently call Acquire.
	Acquire(msgSize uint64, nodeID ids.ShortID)

	// Add a new node to this throttler.
	// Must be called before Acquire(..., [nodeID]) is called.
	// RemoveNode([nodeID]) must have been called since the last time
	// AddNode([nodeID], ...) was called, if any.
	// Its bandwidth allocation refills at a rate of [refillRate].
	// Its bandwidth allocation can hold up to [maxBurstSize] at a time.
	// [maxBurstSize] must be at least the maximum message size.
	// It's safe for multiple goroutines to concurrently call AddNode.
	AddNode(nodeID ids.ShortID)

	// Remove a node from this throttler.
	// AddNode([nodeID], ...) must have been called since
	// the last time RemoveNode([nodeID]) was called, if any.
	// Must be called when we stop reading messages from [nodeID].
	// It's safe for multiple goroutines to concurrently call RemoveNode.
	RemoveNode(nodeID ids.ShortID)
}

Returns a bandwidth throttler that uses a token bucket model, where each token is 1 byte, to rate-limit bandwidth usage. See https://pkg.go.dev/golang.org/x/time/rate#Limiter

func NewBandwidthThrottler

func NewBandwidthThrottler(
	log logging.Logger,
	namespace string,
	registerer prometheus.Registerer,
	config BandwidthThrottlerConfig,
) (BandwidthThrottler, error)

type BandwidthThrottlerConfig

type BandwidthThrottlerConfig struct {
	// Rate at which the inbound bandwidth consumable by a peer replenishes
	RefillRate uint64 `json:"bandwidthRefillRate"`
	// Max amount of consumable bandwidth that can accumulate for a given peer
	MaxBurstSize uint64 `json:"bandwidthMaxBurstRate"`
}

type DialThrottler

type DialThrottler interface {
	// Block until the event associated with this Acquire can happen.
	// If [ctx] is canceled, gives up and returns an error.
	Acquire(ctx context.Context) error
}

func NewDialThrottler

func NewDialThrottler(throttleLimit int) DialThrottler

func NewNoDialThrottler

func NewNoDialThrottler() DialThrottler

type InboundConnUpgradeThrottler

type InboundConnUpgradeThrottler interface {
	// Dispatch starts this InboundConnUpgradeThrottler.
	// Must be called before [ShouldUpgrade].
	// Blocks until [Stop] is called (i.e. should be called in a goroutine.)
	Dispatch()
	// Stop this InboundConnUpgradeThrottler and causes [Dispatch] to return.
	// Should be called when we're done with this InboundConnUpgradeThrottler.
	// This InboundConnUpgradeThrottler must not be used after [Stop] is called.
	Stop()
	// Returns whether we should upgrade an inbound connection from [ipStr].
	// Must only be called after [Dispatch] has been called.
	// If [ip] is a local IP, this method always returns true.
	// Must not be called after [Stop] has been called.
	ShouldUpgrade(ip utils.IPDesc) bool
}

InboundConnUpgradeThrottler returns whether we should upgrade an inbound connection from IP [ipStr]. If ShouldUpgrade(ipStr) returns false, the connection to that IP should be closed. Note that InboundConnUpgradeThrottler rate-limits _upgrading_ of inbound connections, whereas throttledListener rate-limits _acceptance_ of inbound connections.

func NewInboundConnUpgradeThrottler

func NewInboundConnUpgradeThrottler(log logging.Logger, config InboundConnUpgradeThrottlerConfig) InboundConnUpgradeThrottler

Returns an InboundConnUpgradeThrottler that upgrades an inbound connection from a given IP at most every [UpgradeCooldown].

type InboundConnUpgradeThrottlerConfig

type InboundConnUpgradeThrottlerConfig struct {
	// ShouldUpgrade(ipStr) returns true if it has been at least [UpgradeCooldown]
	// since the last time ShouldUpgrade(ipStr) returned true or if
	// ShouldUpgrade(ipStr) has never been called.
	// If <= 0, inbound connections not rate-limited.
	UpgradeCooldown time.Duration `json:"upgradeCooldown"`
	// Maximum number of inbound connections upgraded within [UpgradeCooldown].
	// (As implemented in inboundConnUpgradeThrottler, may actually upgrade
	// [MaxRecentConnsUpgraded+1] due to a race condition but that's fine.)
	// If <= 0, inbound connections not rate-limited.
	MaxRecentConnsUpgraded int `json:"maxRecentConnsUpgraded"`
}

type InboundMsgThrottler

type InboundMsgThrottler interface {
	BandwidthThrottler

	// Blocks until we can read a message of size [msgSize] from [nodeID].
	// For every call to Acquire([msgSize], [nodeID]), we must (!) call
	// Release([msgSize], [nodeID]) when done processing the message
	// (or when we give up trying to read the message.)
	Acquire(msgSize uint64, nodeID ids.ShortID)

	// Mark that we're done processing a message of size [msgSize]
	// from [nodeID].
	Release(msgSize uint64, nodeID ids.ShortID)
}

InboundMsgThrottler rate-limits inbound messages from the network.

func NewInboundMsgThrottler

func NewInboundMsgThrottler(
	log logging.Logger,
	namespace string,
	registerer prometheus.Registerer,
	vdrs validators.Set,
	config InboundMsgThrottlerConfig,
) (InboundMsgThrottler, error)

Returns a new, sybil-safe inbound message throttler.

func NewNoInboundThrottler

func NewNoInboundThrottler() InboundMsgThrottler

Returns an InboundMsgThrottler where Acquire() always returns immediately.

type InboundMsgThrottlerConfig

type InboundMsgThrottlerConfig struct {
	MsgByteThrottlerConfig
	BandwidthThrottlerConfig
	MaxProcessingMsgsPerNode uint64 `json:"maxProcessingMsgsPerNode"`
}

type MsgByteThrottlerConfig

type MsgByteThrottlerConfig struct {
	VdrAllocSize        uint64 `json:"vdrAllocSize"`
	AtLargeAllocSize    uint64 `json:"atLargeAllocSize"`
	NodeMaxAtLargeBytes uint64 `json:"nodeMaxAtLargeBytes"`
}

Used by the sybil-safe inbound and outbound message throttlers

type OutboundMsgThrottler

type OutboundMsgThrottler interface {
	// Returns true if we can queue the message [msg] to be sent to node [nodeID].
	// Returns false if the message should be dropped (not sent to [nodeID]).
	// If this method returns true, Release([msg], [nodeID]) must be called (!) when
	// the message is sent (or when we give up trying to send the message, if applicable.)
	// If this method returns false, do not make a corresponding call to Release.
	Acquire(msg message.OutboundMessage, nodeID ids.ShortID) bool

	// Mark that a message [msg] has been sent to [nodeID] or we have given up
	// sending the message. Must correspond to a previous call to
	// Acquire([msg], [nodeID]) that returned true.
	Release(msg message.OutboundMessage, nodeID ids.ShortID)
}

Rate-limits outgoing messages

func NewNoOutboundThrottler

func NewNoOutboundThrottler() OutboundMsgThrottler

func NewSybilOutboundMsgThrottler

func NewSybilOutboundMsgThrottler(
	log logging.Logger,
	namespace string,
	registerer prometheus.Registerer,
	vdrs validators.Set,
	config MsgByteThrottlerConfig,
) (OutboundMsgThrottler, error)

Jump to

Keyboard shortcuts

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