go-libp2p-resource-manager/limit.go

246 lines
5.5 KiB
Go
Raw Normal View History

2021-12-22 17:39:46 +08:00
package rcmgr
2021-12-23 21:28:14 +08:00
import (
"encoding/json"
"io"
2021-12-23 21:28:14 +08:00
"github.com/libp2p/go-libp2p-core/network"
2021-12-23 23:46:08 +08:00
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
2021-12-23 21:28:14 +08:00
)
2022-01-05 22:54:28 +08:00
// Limit is an object that specifies basic resource limits.
2021-12-22 17:39:46 +08:00
type Limit interface {
// GetMemoryLimit returns the (current) memory limit.
2021-12-22 17:39:46 +08:00
GetMemoryLimit() int64
// GetStreamLimit returns the stream limit, for inbound or outbound streams.
2021-12-23 21:28:14 +08:00
GetStreamLimit(network.Direction) int
2022-01-15 02:10:18 +08:00
// GetStreamTotalLimit returns the total stream limit
GetStreamTotalLimit() int
// GetConnLimit returns the connection limit, for inbound or outbound connections.
2021-12-23 21:28:14 +08:00
GetConnLimit(network.Direction) int
2022-01-15 02:10:18 +08:00
// GetConnTotalLimit returns the total connection limit
GetConnTotalLimit() int
// GetFDLimit returns the file descriptor limit.
2021-12-23 21:28:14 +08:00
GetFDLimit() int
2021-12-22 17:39:46 +08:00
}
2021-12-23 23:46:08 +08:00
2022-01-05 22:54:28 +08:00
// Limiter is the interface for providing limits to the resource manager.
2021-12-23 23:46:08 +08:00
type Limiter interface {
GetSystemLimits() Limit
GetTransientLimits() Limit
GetServiceLimits(svc string) Limit
GetServicePeerLimits(svc string) Limit
2021-12-23 23:46:08 +08:00
GetProtocolLimits(proto protocol.ID) Limit
GetProtocolPeerLimits(proto protocol.ID) Limit
2021-12-23 23:46:08 +08:00
GetPeerLimits(p peer.ID) Limit
GetStreamLimits(p peer.ID) Limit
GetConnLimits() Limit
}
2021-12-24 18:12:44 +08:00
// NewDefaultLimiterFromJSON creates a new limiter by parsing a json configuration,
// using the default limits for fallback.
func NewDefaultLimiterFromJSON(in io.Reader) (Limiter, error) {
return NewLimiterFromJSON(in, DefaultLimits.AutoScale())
}
// NewLimiterFromJSON creates a new limiter by parsing a json configuration.
func NewLimiterFromJSON(in io.Reader, defaults LimitConfig) (Limiter, error) {
cfg, err := readLimiterConfigFromJSON(in, defaults)
if err != nil {
return nil, err
}
return &fixedLimiter{cfg}, nil
}
func readLimiterConfigFromJSON(in io.Reader, defaults LimitConfig) (LimitConfig, error) {
var cfg LimitConfig
if err := json.NewDecoder(in).Decode(&cfg); err != nil {
return LimitConfig{}, err
}
2022-06-19 15:43:31 +08:00
cfg.Apply(defaults)
return cfg, nil
}
2022-06-10 22:01:03 +08:00
// fixedLimiter is a limiter with fixed limits.
type fixedLimiter struct {
LimitConfig
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
var _ Limiter = (*fixedLimiter)(nil)
func NewFixedLimiter(conf LimitConfig) Limiter {
log.Debugw("initializing new limiter with config", "limits", conf)
2022-06-10 22:01:03 +08:00
return &fixedLimiter{LimitConfig: conf}
}
2021-12-24 18:12:44 +08:00
2022-01-06 18:57:37 +08:00
// BaseLimit is a mixin type for basic resource limits.
type BaseLimit struct {
2022-01-15 02:10:18 +08:00
Streams int
2022-01-06 18:57:37 +08:00
StreamsInbound int
StreamsOutbound int
2022-01-15 02:10:18 +08:00
Conns int
2022-01-06 18:57:37 +08:00
ConnsInbound int
ConnsOutbound int
FD int
2022-06-10 22:01:03 +08:00
Memory int64
2022-01-05 22:54:28 +08:00
}
2022-06-19 15:43:31 +08:00
// Apply overwrites all zero-valued limits with the values of l2
// Must not use a pointer receiver.
func (l *BaseLimit) Apply(l2 BaseLimit) {
if l.Streams == 0 {
l.Streams = l2.Streams
}
if l.StreamsInbound == 0 {
l.StreamsInbound = l2.StreamsInbound
}
if l.StreamsOutbound == 0 {
l.StreamsOutbound = l2.StreamsOutbound
}
if l.Conns == 0 {
l.Conns = l2.Conns
}
if l.ConnsInbound == 0 {
l.ConnsInbound = l2.ConnsInbound
}
if l.ConnsOutbound == 0 {
l.ConnsOutbound = l2.ConnsOutbound
}
if l.Memory == 0 {
l.Memory = l2.Memory
}
if l.FD == 0 {
l.FD = l2.FD
}
}
2022-06-10 22:01:03 +08:00
// BaseLimitIncrease is the increase per GB of system memory.
type BaseLimitIncrease struct {
Streams int
StreamsInbound int
StreamsOutbound int
Conns int
ConnsInbound int
ConnsOutbound int
Memory int64
FDFraction float64
}
// Apply overwrites all zero-valued limits with the values of l2
2022-06-19 15:43:31 +08:00
// Must not use a pointer receiver.
func (l *BaseLimitIncrease) Apply(l2 BaseLimitIncrease) {
if l.Streams == 0 {
l.Streams = l2.Streams
}
if l.StreamsInbound == 0 {
l.StreamsInbound = l2.StreamsInbound
}
if l.StreamsOutbound == 0 {
l.StreamsOutbound = l2.StreamsOutbound
}
if l.Conns == 0 {
l.Conns = l2.Conns
}
if l.ConnsInbound == 0 {
l.ConnsInbound = l2.ConnsInbound
}
if l.ConnsOutbound == 0 {
l.ConnsOutbound = l2.ConnsOutbound
}
if l.Memory == 0 {
l.Memory = l2.Memory
}
2022-06-19 15:43:31 +08:00
if l.FDFraction == 0 {
l.FDFraction = l2.FDFraction
}
}
2022-01-05 22:54:28 +08:00
func (l *BaseLimit) GetStreamLimit(dir network.Direction) int {
2021-12-24 18:12:44 +08:00
if dir == network.DirInbound {
return l.StreamsInbound
} else {
return l.StreamsOutbound
}
}
2022-01-15 02:10:18 +08:00
func (l *BaseLimit) GetStreamTotalLimit() int {
return l.Streams
}
2022-01-05 22:54:28 +08:00
func (l *BaseLimit) GetConnLimit(dir network.Direction) int {
2021-12-24 18:12:44 +08:00
if dir == network.DirInbound {
return l.ConnsInbound
} else {
return l.ConnsOutbound
}
}
2022-01-15 02:10:18 +08:00
func (l *BaseLimit) GetConnTotalLimit() int {
return l.Conns
}
2022-01-05 22:54:28 +08:00
func (l *BaseLimit) GetFDLimit() int {
2021-12-24 18:12:44 +08:00
return l.FD
}
2022-06-10 22:01:03 +08:00
func (l *BaseLimit) GetMemoryLimit() int64 {
return l.Memory
}
func (l *fixedLimiter) GetSystemLimits() Limit {
return &l.System
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetTransientLimits() Limit {
return &l.Transient
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetServiceLimits(svc string) Limit {
sl, ok := l.Service[svc]
2021-12-24 18:12:44 +08:00
if !ok {
return &l.ServiceDefault
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
return &sl
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetServicePeerLimits(svc string) Limit {
pl, ok := l.ServicePeer[svc]
if !ok {
return &l.ServicePeerDefault
}
2022-06-10 22:01:03 +08:00
return &pl
}
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetProtocolLimits(proto protocol.ID) Limit {
pl, ok := l.Protocol[proto]
2021-12-24 18:12:44 +08:00
if !ok {
return &l.ProtocolDefault
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
return &pl
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetProtocolPeerLimits(proto protocol.ID) Limit {
pl, ok := l.ProtocolPeer[proto]
if !ok {
return &l.ProtocolPeerDefault
}
2022-06-10 22:01:03 +08:00
return &pl
}
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetPeerLimits(p peer.ID) Limit {
pl, ok := l.Peer[p]
2021-12-24 18:12:44 +08:00
if !ok {
return &l.PeerDefault
2021-12-24 18:12:44 +08:00
}
2022-06-10 22:01:03 +08:00
return &pl
2021-12-24 18:12:44 +08:00
}
2022-01-06 18:57:37 +08:00
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetStreamLimits(_ peer.ID) Limit {
return &l.Stream
2022-01-06 18:57:37 +08:00
}
2022-01-13 21:37:02 +08:00
2022-06-10 22:01:03 +08:00
func (l *fixedLimiter) GetConnLimits() Limit {
return &l.Conn
2022-01-13 21:37:02 +08:00
}