refactor limit defaults for easy access and user manipulation

This commit is contained in:
vyzo 2022-01-16 19:37:15 +02:00
parent ddb39883f9
commit 575eadee04
6 changed files with 330 additions and 217 deletions

104
limit.go
View File

@ -79,6 +79,13 @@ type BaseLimit struct {
FD int
}
// MemoryLimit is a mixin type for memory limits
type MemoryLimit struct {
MemoryFraction float64
MinMemory int64
MaxMemory int64
}
func (l *BaseLimit) GetStreamLimit(dir network.Direction) int {
if dir == network.DirInbound {
return l.StreamsInbound
@ -163,101 +170,12 @@ func (l *BasicLimiter) GetConnLimits() Limit {
return l.ConnLimits
}
// DefaultSystemBaseLimit returns the default BaseLimit for the System Scope.
func DefaultSystemBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 4096,
StreamsOutbound: 16384,
Streams: 16384,
ConnsInbound: 256,
ConnsOutbound: 1024,
Conns: 1024,
FD: 512,
}
func (l *MemoryLimit) GetMemory(memoryCap int64) int64 {
return memoryLimit(memoryCap, l.MemoryFraction, l.MinMemory, l.MaxMemory)
}
// DefaultTransientBaseLimit returns the default BaseLimit for the Transient Scope.
func DefaultTransientBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 128,
StreamsOutbound: 512,
Streams: 512,
ConnsInbound: 32,
ConnsOutbound: 128,
Conns: 128,
FD: 128,
}
}
// DefaultServiceBaseLimit returns the default BaseLimit for Service Scopes.
func DefaultServiceBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 2048,
StreamsOutbound: 8192,
Streams: 8192,
}
}
// DefaultServicePeerBaseLimit returns the default BaseLimit per peer for Service Scopes.
func DefaultServicePeerBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 256,
StreamsOutbound: 512,
Streams: 512,
}
}
// DefaultProtocolBaseLimit returns the default BaseLimit for Protocol Scopes.
func DefaultProtocolBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 1024,
StreamsOutbound: 4096,
Streams: 4096,
}
}
// DefaultProtocolPeerBaseLimit returns the default BaseLimit per peer for Protocol Scopes.
func DefaultProtocolPeerBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 128,
StreamsOutbound: 256,
Streams: 512,
}
}
// DefaultPeerBaseLimit returns the default BaseLimit for Peer Scopes.
func DefaultPeerBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 512,
StreamsOutbound: 1024,
Streams: 1024,
ConnsInbound: 8,
ConnsOutbound: 16,
Conns: 16,
FD: 8,
}
}
// ConnBaseLimit returns the BaseLimit for Connection Scopes.
func ConnBaseLimit() BaseLimit {
return BaseLimit{
ConnsInbound: 1,
ConnsOutbound: 1,
Conns: 1,
FD: 1,
}
}
// StreamBaseLimit returns the BaseLimit for Stream Scopes.
func StreamBaseLimit() BaseLimit {
return BaseLimit{
StreamsInbound: 1,
StreamsOutbound: 1,
Streams: 1,
}
}
func memoryLimit(memoryCap int64, minMemory, maxMemory int64) int64 {
func memoryLimit(memoryCap int64, memFraction float64, minMemory, maxMemory int64) int64 {
memoryCap = int64(float64(memoryCap) * memFraction)
switch {
case memoryCap < minMemory:
return minMemory

View File

@ -32,11 +32,11 @@ type limitConfig struct {
FD int
}
func (cfg *limitConfig) toLimit(base BaseLimit, memFraction float64, minMemory, maxMemory int64) (Limit, error) {
func (cfg *limitConfig) toLimit(base BaseLimit, mem MemoryLimit) (Limit, error) {
if cfg == nil {
mem := memoryLimit(int64(float64(memory.TotalMemory())*memFraction), minMemory, maxMemory)
m := mem.GetMemory(int64(memory.TotalMemory()))
return &StaticLimit{
Memory: mem,
Memory: m,
BaseLimit: base,
}, nil
}
@ -75,20 +75,18 @@ func (cfg *limitConfig) toLimit(base BaseLimit, memFraction float64, minMemory,
return nil, fmt.Errorf("negative memory fraction: %f", cfg.MemoryFraction)
}
if cfg.MemoryFraction > 0 {
memFraction = cfg.MemoryFraction
mem.MemoryFraction = cfg.MemoryFraction
}
if cfg.MinMemory > 0 {
minMemory = cfg.MinMemory
mem.MinMemory = cfg.MinMemory
}
if cfg.MaxMemory > 0 {
maxMemory = cfg.MaxMemory
mem.MaxMemory = cfg.MaxMemory
}
return &DynamicLimit{
MinMemory: minMemory,
MaxMemory: maxMemory,
MemoryFraction: memFraction,
BaseLimit: base,
MemoryLimit: mem,
BaseLimit: base,
}, nil
default:
@ -96,16 +94,67 @@ func (cfg *limitConfig) toLimit(base BaseLimit, memFraction float64, minMemory,
return nil, fmt.Errorf("negative memory fraction: %f", cfg.MemoryFraction)
}
if cfg.MemoryFraction > 0 {
memFraction = cfg.MemoryFraction
mem.MemoryFraction = cfg.MemoryFraction
}
if cfg.MinMemory > 0 {
minMemory = cfg.MinMemory
mem.MinMemory = cfg.MinMemory
}
if cfg.MaxMemory > 0 {
maxMemory = cfg.MaxMemory
mem.MaxMemory = cfg.MaxMemory
}
mem := memoryLimit(int64(float64(memory.TotalMemory())*memFraction), minMemory, maxMemory)
m := mem.GetMemory(int64(memory.TotalMemory()))
return &StaticLimit{
Memory: m,
BaseLimit: base,
}, nil
}
}
func (cfg *limitConfig) toLimitFixed(base BaseLimit, mem int64) (Limit, error) {
if cfg == nil {
return &StaticLimit{
Memory: mem,
BaseLimit: base,
}, nil
}
if cfg.Streams > 0 {
base.Streams = cfg.Streams
}
if cfg.StreamsInbound > 0 {
base.StreamsInbound = cfg.StreamsInbound
}
if cfg.StreamsOutbound > 0 {
base.StreamsOutbound = cfg.StreamsOutbound
}
if cfg.Conns > 0 {
base.Conns = cfg.Conns
}
if cfg.ConnsInbound > 0 {
base.ConnsInbound = cfg.ConnsInbound
}
if cfg.ConnsOutbound > 0 {
base.ConnsOutbound = cfg.ConnsOutbound
}
if cfg.FD > 0 {
base.FD = cfg.FD
}
switch {
case cfg.Memory > 0:
return &StaticLimit{
Memory: cfg.Memory,
BaseLimit: base,
}, nil
case cfg.Dynamic:
return nil, fmt.Errorf("cannot specify dynamic limit for fixed memory limit")
default:
if cfg.MemoryFraction > 0 || cfg.MinMemory > 0 || cfg.MaxMemory > 0 {
return nil, fmt.Errorf("cannot specify dynamic range for fixed memory limit")
}
return &StaticLimit{
Memory: mem,
BaseLimit: base,
@ -134,8 +183,14 @@ type limiterConfig struct {
Stream *limitConfig
}
// NewDefaultLimiterFromJSON creates a new limiter by parsing a json configuration,
// using the default limits for fallback.
func NewDefaultLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
return NewLimiterFromJSON(in, DefaultLimits)
}
// NewLimiterFromJSON creates a new limiter by parsing a json configuration.
func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
func NewLimiterFromJSON(in io.Reader, defaults DefaultLimitConfig) (*BasicLimiter, error) {
jin := json.NewDecoder(in)
var cfg limiterConfig
@ -147,22 +202,22 @@ func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
limiter := new(BasicLimiter)
var err error
limiter.SystemLimits, err = cfg.System.toLimit(DefaultSystemBaseLimit(), 0.125, 128<<20, 1<<30)
limiter.SystemLimits, err = cfg.System.toLimit(defaults.SystemBaseLimit, defaults.SystemMemory)
if err != nil {
return nil, fmt.Errorf("invalid system limit: %w", err)
}
limiter.TransientLimits, err = cfg.Transient.toLimit(DefaultTransientBaseLimit(), 0.0078125, 64<<20, 128<<20)
limiter.TransientLimits, err = cfg.Transient.toLimit(defaults.TransientBaseLimit, defaults.TransientMemory)
if err != nil {
return nil, fmt.Errorf("invalid transient limit: %w", err)
}
limiter.DefaultServiceLimits, err = cfg.ServiceDefault.toLimit(DefaultServiceBaseLimit(), 0.03125, 64<<20, 512<<20)
limiter.DefaultServiceLimits, err = cfg.ServiceDefault.toLimit(defaults.ServiceBaseLimit, defaults.ServiceMemory)
if err != nil {
return nil, fmt.Errorf("invlaid default service limit: %w", err)
}
limiter.DefaultServicePeerLimits, err = cfg.ServicePeerDefault.toLimit(DefaultServicePeerBaseLimit(), 0.0078125, 16<<20, 64<<20)
limiter.DefaultServicePeerLimits, err = cfg.ServicePeerDefault.toLimit(defaults.ServicePeerBaseLimit, defaults.ServicePeerMemory)
if err != nil {
return nil, fmt.Errorf("invlaid default service peer limit: %w", err)
}
@ -170,7 +225,7 @@ func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
if len(cfg.Service) > 0 {
limiter.ServiceLimits = make(map[string]Limit, len(cfg.Service))
for svc, cfgLimit := range cfg.Service {
limiter.ServiceLimits[svc], err = cfgLimit.toLimit(DefaultServiceBaseLimit(), 0.03125, 64<<20, 512<<20)
limiter.ServiceLimits[svc], err = cfgLimit.toLimit(defaults.ServiceBaseLimit, defaults.ServiceMemory)
if err != nil {
return nil, fmt.Errorf("invalid service limit for %s: %w", svc, err)
}
@ -180,19 +235,19 @@ func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
if len(cfg.ServicePeer) > 0 {
limiter.ServicePeerLimits = make(map[string]Limit, len(cfg.ServicePeer))
for svc, cfgLimit := range cfg.ServicePeer {
limiter.ServicePeerLimits[svc], err = cfgLimit.toLimit(DefaultServicePeerBaseLimit(), 0.0078125, 16<<20, 64<<20)
limiter.ServicePeerLimits[svc], err = cfgLimit.toLimit(defaults.ServicePeerBaseLimit, defaults.ServicePeerMemory)
if err != nil {
return nil, fmt.Errorf("invalid service peer limit for %s: %w", svc, err)
}
}
}
limiter.DefaultProtocolLimits, err = cfg.ProtocolDefault.toLimit(DefaultProtocolBaseLimit(), 0.0078125, 64<<20, 128<<20)
limiter.DefaultProtocolLimits, err = cfg.ProtocolDefault.toLimit(defaults.ProtocolBaseLimit, defaults.ProtocolMemory)
if err != nil {
return nil, fmt.Errorf("invlaid default protocol limit: %w", err)
}
limiter.DefaultProtocolPeerLimits, err = cfg.ProtocolPeerDefault.toLimit(DefaultProtocolPeerBaseLimit(), 0.0078125, 16<<20, 64<<20)
limiter.DefaultProtocolPeerLimits, err = cfg.ProtocolPeerDefault.toLimit(defaults.ProtocolPeerBaseLimit, defaults.ProtocolPeerMemory)
if err != nil {
return nil, fmt.Errorf("invlaid default protocol peer limit: %w", err)
}
@ -200,7 +255,7 @@ func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
if len(cfg.Protocol) > 0 {
limiter.ProtocolLimits = make(map[protocol.ID]Limit, len(cfg.Protocol))
for p, cfgLimit := range cfg.Protocol {
limiter.ProtocolLimits[protocol.ID(p)], err = cfgLimit.toLimit(DefaultProtocolBaseLimit(), 0.0078125, 64<<20, 128<<20)
limiter.ProtocolLimits[protocol.ID(p)], err = cfgLimit.toLimit(defaults.ProtocolBaseLimit, defaults.ProtocolMemory)
if err != nil {
return nil, fmt.Errorf("invalid service limit for %s: %w", p, err)
}
@ -210,14 +265,14 @@ func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
if len(cfg.ProtocolPeer) > 0 {
limiter.ProtocolPeerLimits = make(map[protocol.ID]Limit, len(cfg.ProtocolPeer))
for p, cfgLimit := range cfg.ProtocolPeer {
limiter.ProtocolPeerLimits[protocol.ID(p)], err = cfgLimit.toLimit(DefaultProtocolPeerBaseLimit(), 0.0078125, 16<<20, 64<<20)
limiter.ProtocolPeerLimits[protocol.ID(p)], err = cfgLimit.toLimit(defaults.ProtocolPeerBaseLimit, defaults.ProtocolPeerMemory)
if err != nil {
return nil, fmt.Errorf("invalid service peer limit for %s: %w", p, err)
}
}
}
limiter.DefaultPeerLimits, err = cfg.PeerDefault.toLimit(DefaultPeerBaseLimit(), 0.0078125, 64<<20, 1288<<20)
limiter.DefaultPeerLimits, err = cfg.PeerDefault.toLimit(defaults.PeerBaseLimit, defaults.PeerMemory)
if err != nil {
return nil, fmt.Errorf("invalid peer limit: %w", err)
}
@ -229,19 +284,19 @@ func NewLimiterFromJSON(in io.Reader) (*BasicLimiter, error) {
if err != nil {
return nil, fmt.Errorf("invalid peer ID %s: %w", p, err)
}
limiter.PeerLimits[pid], err = cfgLimit.toLimit(DefaultPeerBaseLimit(), 0.0078125, 64<<20, 1288<<20)
limiter.PeerLimits[pid], err = cfgLimit.toLimit(defaults.PeerBaseLimit, defaults.PeerMemory)
if err != nil {
return nil, fmt.Errorf("invalid peer limit for %s: %w", p, err)
}
}
}
limiter.ConnLimits, err = cfg.Conn.toLimit(ConnBaseLimit(), 1, 1<<20, 1<<20)
limiter.ConnLimits, err = cfg.Conn.toLimitFixed(defaults.ConnBaseLimit, defaults.ConnMemory)
if err != nil {
return nil, fmt.Errorf("invalid conn limit: %w", err)
}
limiter.StreamLimits, err = cfg.Stream.toLimit(StreamBaseLimit(), 1, 16<<20, 16<<20)
limiter.StreamLimits, err = cfg.Stream.toLimitFixed(defaults.StreamBaseLimit, defaults.StreamMemory)
if err != nil {
return nil, fmt.Errorf("invalid stream limit: %w", err)
}

View File

@ -12,14 +12,16 @@ func TestLimitConfigParser(t *testing.T) {
require.NoError(t, err)
defer in.Close()
limiter, err := NewLimiterFromJSON(in)
limiter, err := NewDefaultLimiterFromJSON(in)
require.NoError(t, err)
require.Equal(t,
&DynamicLimit{
MinMemory: 16384,
MaxMemory: 65536,
MemoryFraction: 0.125,
MemoryLimit: MemoryLimit{
MinMemory: 16384,
MaxMemory: 65536,
MemoryFraction: 0.125,
},
BaseLimit: BaseLimit{
Streams: 64,
StreamsInbound: 32,
@ -35,21 +37,21 @@ func TestLimitConfigParser(t *testing.T) {
require.Equal(t,
&StaticLimit{
Memory: 4096,
BaseLimit: DefaultTransientBaseLimit(),
BaseLimit: DefaultLimits.TransientBaseLimit,
},
limiter.TransientLimits)
require.Equal(t,
&StaticLimit{
Memory: 8192,
BaseLimit: DefaultServiceBaseLimit(),
BaseLimit: DefaultLimits.ServiceBaseLimit,
},
limiter.DefaultServiceLimits)
require.Equal(t,
&StaticLimit{
Memory: 2048,
BaseLimit: DefaultServicePeerBaseLimit(),
BaseLimit: DefaultLimits.ServicePeerBaseLimit,
},
limiter.DefaultServicePeerLimits)
@ -57,7 +59,7 @@ func TestLimitConfigParser(t *testing.T) {
require.Equal(t,
&StaticLimit{
Memory: 8192,
BaseLimit: DefaultServiceBaseLimit(),
BaseLimit: DefaultLimits.ServiceBaseLimit,
},
limiter.ServiceLimits["A"])
@ -65,20 +67,20 @@ func TestLimitConfigParser(t *testing.T) {
require.Equal(t,
&StaticLimit{
Memory: 4096,
BaseLimit: DefaultServicePeerBaseLimit(),
BaseLimit: DefaultLimits.ServicePeerBaseLimit,
},
limiter.ServicePeerLimits["A"])
require.Equal(t,
&StaticLimit{
Memory: 2048,
BaseLimit: DefaultProtocolBaseLimit(),
BaseLimit: DefaultLimits.ProtocolBaseLimit,
},
limiter.DefaultProtocolLimits)
require.Equal(t,
&StaticLimit{
Memory: 1024,
BaseLimit: DefaultProtocolPeerBaseLimit(),
BaseLimit: DefaultLimits.ProtocolPeerBaseLimit,
},
limiter.DefaultProtocolPeerLimits)
@ -86,7 +88,7 @@ func TestLimitConfigParser(t *testing.T) {
require.Equal(t,
&StaticLimit{
Memory: 8192,
BaseLimit: DefaultProtocolBaseLimit(),
BaseLimit: DefaultLimits.ProtocolBaseLimit,
},
limiter.ProtocolLimits["/A"])
@ -94,28 +96,28 @@ func TestLimitConfigParser(t *testing.T) {
require.Equal(t,
&StaticLimit{
Memory: 4096,
BaseLimit: DefaultProtocolPeerBaseLimit(),
BaseLimit: DefaultLimits.ProtocolPeerBaseLimit,
},
limiter.ProtocolPeerLimits["/A"])
require.Equal(t,
&StaticLimit{
Memory: 4096,
BaseLimit: DefaultPeerBaseLimit(),
BaseLimit: DefaultLimits.PeerBaseLimit,
},
limiter.DefaultPeerLimits)
require.Equal(t,
&StaticLimit{
Memory: 1 << 20,
BaseLimit: ConnBaseLimit(),
BaseLimit: DefaultLimits.ConnBaseLimit,
},
limiter.ConnLimits)
require.Equal(t,
&StaticLimit{
Memory: 16 << 20,
BaseLimit: StreamBaseLimit(),
BaseLimit: DefaultLimits.StreamBaseLimit,
},
limiter.StreamLimits)

147
limit_defaults.go Normal file
View File

@ -0,0 +1,147 @@
package rcmgr
// DefaultLimitConfig is a struct for configuring default limits.
type DefaultLimitConfig struct {
SystemBaseLimit BaseLimit
SystemMemory MemoryLimit
TransientBaseLimit BaseLimit
TransientMemory MemoryLimit
ServiceBaseLimit BaseLimit
ServiceMemory MemoryLimit
ServicePeerBaseLimit BaseLimit
ServicePeerMemory MemoryLimit
ProtocolBaseLimit BaseLimit
ProtocolMemory MemoryLimit
ProtocolPeerBaseLimit BaseLimit
ProtocolPeerMemory MemoryLimit
PeerBaseLimit BaseLimit
PeerMemory MemoryLimit
ConnBaseLimit BaseLimit
ConnMemory int64
StreamBaseLimit BaseLimit
StreamMemory int64
}
// DefaultLimits are the limits used by the default limiter constructors.
var DefaultLimits = DefaultLimitConfig{
SystemBaseLimit: BaseLimit{
StreamsInbound: 4096,
StreamsOutbound: 16384,
Streams: 16384,
ConnsInbound: 256,
ConnsOutbound: 1024,
Conns: 1024,
FD: 512,
},
SystemMemory: MemoryLimit{
MemoryFraction: 0.125,
MinMemory: 128 << 20,
MaxMemory: 1 << 30,
},
TransientBaseLimit: BaseLimit{
StreamsInbound: 128,
StreamsOutbound: 512,
Streams: 512,
ConnsInbound: 32,
ConnsOutbound: 128,
Conns: 128,
FD: 128,
},
TransientMemory: MemoryLimit{
MemoryFraction: 1,
MinMemory: 64 << 20,
MaxMemory: 64 << 20,
},
ServiceBaseLimit: BaseLimit{
StreamsInbound: 2048,
StreamsOutbound: 8192,
Streams: 8192,
},
ServiceMemory: MemoryLimit{
MemoryFraction: 0.125 / 4,
MinMemory: 64 << 20,
MaxMemory: 256 << 20,
},
ServicePeerBaseLimit: BaseLimit{
StreamsInbound: 256,
StreamsOutbound: 512,
Streams: 512,
},
ServicePeerMemory: MemoryLimit{
MemoryFraction: 0.125 / 16,
MinMemory: 16 << 20,
MaxMemory: 64 << 20,
},
ProtocolBaseLimit: BaseLimit{
StreamsInbound: 1024,
StreamsOutbound: 4096,
Streams: 4096,
},
ProtocolMemory: MemoryLimit{
MemoryFraction: 0.125 / 8,
MinMemory: 64 << 20,
MaxMemory: 128 << 20,
},
ProtocolPeerBaseLimit: BaseLimit{
StreamsInbound: 128,
StreamsOutbound: 256,
Streams: 512,
},
ProtocolPeerMemory: MemoryLimit{
MemoryFraction: 0.125 / 16,
MinMemory: 16 << 20,
MaxMemory: 64 << 20,
},
PeerBaseLimit: BaseLimit{
StreamsInbound: 512,
StreamsOutbound: 1024,
Streams: 1024,
ConnsInbound: 8,
ConnsOutbound: 16,
Conns: 16,
FD: 8,
},
PeerMemory: MemoryLimit{
MemoryFraction: 0.125 / 16,
MinMemory: 64 << 20,
MaxMemory: 128 << 20,
},
ConnBaseLimit: BaseLimit{
ConnsInbound: 1,
ConnsOutbound: 1,
Conns: 1,
FD: 1,
},
ConnMemory: 1 << 20,
StreamBaseLimit: BaseLimit{
StreamsInbound: 1,
StreamsOutbound: 1,
Streams: 1,
},
StreamMemory: 16 << 20,
}

View File

@ -9,14 +9,7 @@ import (
// DynamicLimit is a limit with dynamic memory values, based on available (free) memory
type DynamicLimit struct {
BaseLimit
// MinMemory is the minimum memory for this limit
MinMemory int64
// MaxMemory is the maximum memory for this limit
MaxMemory int64
// MemoryFraction is the fraction of available memory allowed for this limit,
// bounded by [MinMemory, MaxMemory]
MemoryFraction float64
MemoryLimit
}
var _ Limit = (*DynamicLimit)(nil)
@ -31,18 +24,16 @@ func (l *DynamicLimit) GetMemoryLimit() int64 {
runtime.ReadMemStats(&memstat)
freemem += (memstat.HeapInuse - memstat.HeapAlloc) + (memstat.HeapIdle - memstat.HeapReleased)
limit := int64(float64(freemem) * l.MemoryFraction)
return memoryLimit(limit, l.MinMemory, l.MaxMemory)
return l.MemoryLimit.GetMemory(int64(freemem))
}
func (l *DynamicLimit) WithMemoryLimit(memFraction float64, minMemory, maxMemory int64) Limit {
r := new(DynamicLimit)
*r = *l
r.MemoryFraction *= memFraction
r.MinMemory = minMemory
r.MaxMemory = maxMemory
r.MemoryLimit.MemoryFraction *= memFraction
r.MemoryLimit.MinMemory = minMemory
r.MemoryLimit.MaxMemory = maxMemory
return r
}
@ -78,61 +69,49 @@ func (l *DynamicLimit) WithFDLimit(numFD int) Limit {
return r
}
// NewDynamicLimiter creates a limiter with default limits and a memory cap dynamically computed
// based on available memory. minMemory and maxMemory specify the system memory bounds,
// while memFraction specifies the fraction of available memory available for the system, within
// the specified bounds.
func NewDynamicLimiter(memFraction float64, minMemory, maxMemory int64) *BasicLimiter {
// NewDefaultDynamicLimiter creates a limiter with default limits and a memory cap
// dynamically computed based on available memory.
func NewDefaultDynamicLimiter() *BasicLimiter {
return NewDynamicLimiter(DefaultLimits)
}
// NewDynamicLimiter crates a dynamic limiter with the specified defaults
func NewDynamicLimiter(cfg DefaultLimitConfig) *BasicLimiter {
system := &DynamicLimit{
MinMemory: minMemory,
MaxMemory: maxMemory,
MemoryFraction: memFraction,
BaseLimit: DefaultSystemBaseLimit(),
MemoryLimit: cfg.SystemMemory,
BaseLimit: cfg.SystemBaseLimit,
}
transient := &DynamicLimit{
MinMemory: 64 << 20,
MaxMemory: 128 << 20,
MemoryFraction: memFraction / 16,
BaseLimit: DefaultTransientBaseLimit(),
MemoryLimit: cfg.TransientMemory,
BaseLimit: cfg.TransientBaseLimit,
}
svc := &DynamicLimit{
MinMemory: 64 << 20,
MaxMemory: 512 << 20,
MemoryFraction: memFraction / 4,
BaseLimit: DefaultServiceBaseLimit(),
MemoryLimit: cfg.ServiceMemory,
BaseLimit: cfg.ServiceBaseLimit,
}
svcPeer := &DynamicLimit{
MinMemory: 16 << 20,
MaxMemory: 64 << 20,
MemoryFraction: memFraction / 16,
BaseLimit: DefaultServicePeerBaseLimit(),
MemoryLimit: cfg.ServicePeerMemory,
BaseLimit: cfg.ServicePeerBaseLimit,
}
proto := &DynamicLimit{
MinMemory: 64 << 20,
MaxMemory: 128 << 20,
MemoryFraction: memFraction / 16,
BaseLimit: DefaultProtocolBaseLimit(),
MemoryLimit: cfg.ProtocolMemory,
BaseLimit: cfg.ProtocolBaseLimit,
}
protoPeer := &DynamicLimit{
MinMemory: 16 << 20,
MaxMemory: 64 << 20,
MemoryFraction: memFraction / 16,
BaseLimit: DefaultProtocolPeerBaseLimit(),
MemoryLimit: cfg.ProtocolPeerMemory,
BaseLimit: cfg.ProtocolPeerBaseLimit,
}
peer := &DynamicLimit{
MinMemory: 64 << 20,
MaxMemory: 128 << 20,
MemoryFraction: memFraction / 16,
BaseLimit: DefaultPeerBaseLimit(),
MemoryLimit: cfg.PeerMemory,
BaseLimit: cfg.PeerBaseLimit,
}
conn := &StaticLimit{
Memory: 1 << 20,
BaseLimit: ConnBaseLimit(),
Memory: cfg.ConnMemory,
BaseLimit: cfg.ConnBaseLimit,
}
stream := &StaticLimit{
Memory: 16 << 20,
BaseLimit: StreamBaseLimit(),
Memory: cfg.StreamMemory,
BaseLimit: cfg.StreamBaseLimit,
}
return &BasicLimiter{

View File

@ -61,55 +61,67 @@ func (l *StaticLimit) WithFDLimit(numFD int) Limit {
return r
}
// NewStaticLimiter creates a limiter with default base limits and a system memory cap specified as
// a fraction of total system memory. The assigned memory will not be less than minMemory or more
// than maxMemory.
func NewStaticLimiter(memFraction float64, minMemory, maxMemory int64) *BasicLimiter {
memoryCap := memoryLimit(int64(float64(memory.TotalMemory())*memFraction), minMemory, maxMemory)
return newDefaultStaticLimiter(memoryCap)
// NewDefaultStaticLimiter creates a static limiter with default base limits and a system memory cap
// specified as a fraction of total system memory. The assigned memory will not be less than
// minMemory or more than maxMemory.
func NewDefaultStaticLimiter(memFraction float64, minMemory, maxMemory int64) *BasicLimiter {
memoryCap := memoryLimit(int64(memory.TotalMemory()), memFraction, minMemory, maxMemory)
return NewStaticLimiter(memoryCap, DefaultLimits)
}
// NewFixedLimiter creates a limiter with default base limits and a specified system memory cap.
func NewFixedLimiter(memoryCap int64) *BasicLimiter {
return newDefaultStaticLimiter(memoryCap)
// NewDefaultFixedLimiter creates a static limiter with default base limits and a specified system
// memory cap.
func NewDefaultFixedLimiter(memoryCap int64) *BasicLimiter {
return NewStaticLimiter(memoryCap, DefaultLimits)
}
func newDefaultStaticLimiter(memoryCap int64) *BasicLimiter {
// NewDefaultLimiter creates a static limiter with the default limits
func NewDefaultLimiter() *BasicLimiter {
return NewDefaultStaticLimiter(
DefaultLimits.SystemMemory.MemoryFraction,
DefaultLimits.SystemMemory.MinMemory,
DefaultLimits.SystemMemory.MaxMemory,
)
}
// NewStaticLimiter creates a static limiter using the specified system memory cap and default
// limit config.
func NewStaticLimiter(memoryCap int64, cfg DefaultLimitConfig) *BasicLimiter {
system := &StaticLimit{
Memory: memoryCap,
BaseLimit: DefaultSystemBaseLimit(),
BaseLimit: cfg.SystemBaseLimit,
}
transient := &StaticLimit{
Memory: memoryLimit(memoryCap/16, 64<<20, 128<<20),
BaseLimit: DefaultTransientBaseLimit(),
Memory: cfg.SystemMemory.GetMemory(memoryCap),
BaseLimit: cfg.TransientBaseLimit,
}
svc := &StaticLimit{
Memory: memoryLimit(memoryCap/4, 64<<20, 512<<20),
BaseLimit: DefaultServiceBaseLimit(),
Memory: cfg.ServiceMemory.GetMemory(memoryCap),
BaseLimit: cfg.ServiceBaseLimit,
}
svcPeer := &StaticLimit{
Memory: memoryLimit(memoryCap/16, 16<<20, 64<<20),
BaseLimit: DefaultServicePeerBaseLimit(),
Memory: cfg.ServicePeerMemory.GetMemory(memoryCap),
BaseLimit: cfg.ServicePeerBaseLimit,
}
proto := &StaticLimit{
Memory: memoryLimit(memoryCap/16, 64<<20, 128<<20),
BaseLimit: DefaultProtocolBaseLimit(),
Memory: cfg.ProtocolMemory.GetMemory(memoryCap),
BaseLimit: cfg.ProtocolBaseLimit,
}
protoPeer := &StaticLimit{
Memory: memoryLimit(memoryCap/16, 16<<20, 64<<20),
BaseLimit: DefaultProtocolPeerBaseLimit(),
Memory: cfg.ProtocolPeerMemory.GetMemory(memoryCap),
BaseLimit: cfg.ProtocolPeerBaseLimit,
}
peer := &StaticLimit{
Memory: memoryLimit(memoryCap/16, 64<<20, 128<<20),
BaseLimit: DefaultPeerBaseLimit(),
Memory: cfg.PeerMemory.GetMemory(memoryCap),
BaseLimit: cfg.PeerBaseLimit,
}
conn := &StaticLimit{
Memory: 1 << 20,
BaseLimit: ConnBaseLimit(),
Memory: cfg.ConnMemory,
BaseLimit: cfg.ConnBaseLimit,
}
stream := &StaticLimit{
Memory: 16 << 20,
BaseLimit: StreamBaseLimit(),
Memory: cfg.StreamMemory,
BaseLimit: cfg.StreamBaseLimit,
}
return &BasicLimiter{