mirror of
https://github.com/libp2p/go-libp2p-resource-manager.git
synced 2025-02-05 01:00:19 +08:00
refactor limiters
This commit is contained in:
parent
cd110100ca
commit
066de7c0c9
289
limit.go
289
limit.go
@ -4,9 +4,6 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
"github.com/elastic/gosigar"
|
||||
"github.com/pbnjay/memory"
|
||||
)
|
||||
|
||||
// Limit is an object that specifies basic resource limits.
|
||||
@ -28,37 +25,6 @@ type Limiter interface {
|
||||
GetConnLimits() Limit
|
||||
}
|
||||
|
||||
type BaseLimit struct {
|
||||
StreamsInbound int
|
||||
StreamsOutbound int
|
||||
ConnsInbound int
|
||||
ConnsOutbound int
|
||||
FD int
|
||||
}
|
||||
|
||||
// StaticLimit is a limit with static values.
|
||||
type StaticLimit struct {
|
||||
BaseLimit
|
||||
Memory int64
|
||||
}
|
||||
|
||||
var _ Limit = (*StaticLimit)(nil)
|
||||
|
||||
// DynamicLimit is a limit with dynamic memory values, based on available 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 int
|
||||
}
|
||||
|
||||
var _ Limit = (*DynamicLimit)(nil)
|
||||
|
||||
// BasicLimiter is a limiter with fixed limits.
|
||||
type BasicLimiter struct {
|
||||
SystemLimits Limit
|
||||
@ -75,188 +41,13 @@ type BasicLimiter struct {
|
||||
|
||||
var _ Limiter = (*BasicLimiter)(nil)
|
||||
|
||||
// NewStaticLimiter creates a limiter with default limits and a system memory cap; if the
|
||||
// system memory cap is 0, then 1/8th of the total memory is used.
|
||||
func NewStaticLimiter(memoryCap int64) *BasicLimiter {
|
||||
if memoryCap == 0 {
|
||||
memoryCap = int64(memory.TotalMemory() / 8)
|
||||
}
|
||||
|
||||
system := &StaticLimit{
|
||||
Memory: memoryCap,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 4096,
|
||||
StreamsOutbound: 16384,
|
||||
ConnsInbound: 256,
|
||||
ConnsOutbound: 512,
|
||||
FD: 512,
|
||||
},
|
||||
}
|
||||
transient := &StaticLimit{
|
||||
Memory: memoryCap / 16,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 128,
|
||||
StreamsOutbound: 512,
|
||||
ConnsInbound: 32,
|
||||
ConnsOutbound: 128,
|
||||
FD: 128,
|
||||
},
|
||||
}
|
||||
svc := &StaticLimit{
|
||||
Memory: memoryCap / 2,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 2048,
|
||||
StreamsOutbound: 8192,
|
||||
},
|
||||
}
|
||||
proto := &StaticLimit{
|
||||
Memory: memoryCap / 4,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 1024,
|
||||
StreamsOutbound: 4096,
|
||||
},
|
||||
}
|
||||
peer := &StaticLimit{
|
||||
Memory: memoryCap / 16,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 512,
|
||||
StreamsOutbound: 2048,
|
||||
ConnsInbound: 8,
|
||||
ConnsOutbound: 16,
|
||||
FD: 8,
|
||||
},
|
||||
}
|
||||
conn := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: BaseLimit{
|
||||
ConnsInbound: 1,
|
||||
ConnsOutbound: 1,
|
||||
FD: 1,
|
||||
},
|
||||
}
|
||||
stream := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 1,
|
||||
StreamsOutbound: 1,
|
||||
},
|
||||
}
|
||||
|
||||
return &BasicLimiter{
|
||||
SystemLimits: system,
|
||||
TransientLimits: transient,
|
||||
DefaultServiceLimits: svc,
|
||||
DefaultProtocolLimits: proto,
|
||||
DefaultPeerLimits: peer,
|
||||
ConnLimits: conn,
|
||||
StreamLimits: stream,
|
||||
}
|
||||
}
|
||||
|
||||
// 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(minMemory, maxMemory int64, memFraction int) *BasicLimiter {
|
||||
system := &DynamicLimit{
|
||||
MinMemory: minMemory,
|
||||
MaxMemory: maxMemory,
|
||||
MemoryFraction: memFraction,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 4096,
|
||||
StreamsOutbound: 16384,
|
||||
ConnsInbound: 256,
|
||||
ConnsOutbound: 512,
|
||||
FD: 512,
|
||||
},
|
||||
}
|
||||
transient := &DynamicLimit{
|
||||
MinMemory: minMemory / 16,
|
||||
MaxMemory: maxMemory / 16,
|
||||
MemoryFraction: memFraction * 16,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 128,
|
||||
StreamsOutbound: 512,
|
||||
ConnsInbound: 32,
|
||||
ConnsOutbound: 128,
|
||||
FD: 128,
|
||||
},
|
||||
}
|
||||
svc := &DynamicLimit{
|
||||
MinMemory: minMemory / 2,
|
||||
MaxMemory: maxMemory / 2,
|
||||
MemoryFraction: memFraction * 2,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 2048,
|
||||
StreamsOutbound: 8192,
|
||||
},
|
||||
}
|
||||
proto := &DynamicLimit{
|
||||
MinMemory: minMemory / 4,
|
||||
MaxMemory: maxMemory / 4,
|
||||
MemoryFraction: memFraction * 4,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 1024,
|
||||
StreamsOutbound: 4096,
|
||||
},
|
||||
}
|
||||
peer := &DynamicLimit{
|
||||
MinMemory: minMemory / 16,
|
||||
MaxMemory: maxMemory / 16,
|
||||
MemoryFraction: memFraction * 16,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 512,
|
||||
StreamsOutbound: 2048,
|
||||
ConnsInbound: 8,
|
||||
ConnsOutbound: 16,
|
||||
FD: 8,
|
||||
},
|
||||
}
|
||||
conn := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: BaseLimit{
|
||||
ConnsInbound: 1,
|
||||
ConnsOutbound: 1,
|
||||
FD: 1,
|
||||
},
|
||||
}
|
||||
stream := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: BaseLimit{
|
||||
StreamsInbound: 1,
|
||||
StreamsOutbound: 1,
|
||||
},
|
||||
}
|
||||
|
||||
return &BasicLimiter{
|
||||
SystemLimits: system,
|
||||
TransientLimits: transient,
|
||||
DefaultServiceLimits: svc,
|
||||
DefaultProtocolLimits: proto,
|
||||
DefaultPeerLimits: peer,
|
||||
ConnLimits: conn,
|
||||
StreamLimits: stream,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *StaticLimit) GetMemoryLimit() int64 {
|
||||
return l.Memory
|
||||
}
|
||||
|
||||
func (l *DynamicLimit) GetMemoryLimit() int64 {
|
||||
var mem gosigar.Mem
|
||||
if err := mem.Get(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
limit := int64(mem.ActualFree) / int64(l.MemoryFraction)
|
||||
if limit < l.MinMemory {
|
||||
limit = l.MinMemory
|
||||
} else if limit > l.MaxMemory {
|
||||
limit = l.MaxMemory
|
||||
}
|
||||
|
||||
return limit
|
||||
// BaseLimit is a mixin type for basic resource limits.
|
||||
type BaseLimit struct {
|
||||
StreamsInbound int
|
||||
StreamsOutbound int
|
||||
ConnsInbound int
|
||||
ConnsOutbound int
|
||||
FD int
|
||||
}
|
||||
|
||||
func (l *BaseLimit) GetStreamLimit(dir network.Direction) int {
|
||||
@ -318,3 +109,69 @@ func (l *BasicLimiter) GetStreamLimits(p peer.ID) Limit {
|
||||
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,
|
||||
ConnsInbound: 256,
|
||||
ConnsOutbound: 512,
|
||||
FD: 512,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultTransientBaseLimit returns the default BaseLimit for the Transient Scope.
|
||||
func DefaultTransientBaseLimit() BaseLimit {
|
||||
return BaseLimit{
|
||||
StreamsInbound: 128,
|
||||
StreamsOutbound: 512,
|
||||
ConnsInbound: 32,
|
||||
ConnsOutbound: 128,
|
||||
FD: 128,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultServiceBaseLimit returns the default BaseLimit for Service Scopes.
|
||||
func DefaultServiceBaseLimit() BaseLimit {
|
||||
return BaseLimit{
|
||||
StreamsInbound: 2048,
|
||||
StreamsOutbound: 8192,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultProtocolBaseLimit returns the default BaseLimit for Protocol Scopes.
|
||||
func DefaultProtocolBaseLimit() BaseLimit {
|
||||
return BaseLimit{
|
||||
StreamsInbound: 1024,
|
||||
StreamsOutbound: 4096,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultPeerBaseLimit returns the default BaseLimit for Peer Scopes.
|
||||
func DefaultPeerBaseLimit() BaseLimit {
|
||||
return BaseLimit{
|
||||
StreamsInbound: 512,
|
||||
StreamsOutbound: 2048,
|
||||
ConnsInbound: 8,
|
||||
ConnsOutbound: 16,
|
||||
FD: 8,
|
||||
}
|
||||
}
|
||||
|
||||
// ConnBaseLimit returns the BaseLimit for Connection Scopes.
|
||||
func ConnBaseLimit() BaseLimit {
|
||||
return BaseLimit{
|
||||
ConnsInbound: 1,
|
||||
ConnsOutbound: 1,
|
||||
FD: 1,
|
||||
}
|
||||
}
|
||||
|
||||
// StreamBaseLimit returns the BaseLimit for Stream Scopes.
|
||||
func StreamBaseLimit() BaseLimit {
|
||||
return BaseLimit{
|
||||
StreamsInbound: 1,
|
||||
StreamsOutbound: 1,
|
||||
}
|
||||
}
|
||||
|
91
limit_dynamic.go
Normal file
91
limit_dynamic.go
Normal file
@ -0,0 +1,91 @@
|
||||
package rcmgr
|
||||
|
||||
import (
|
||||
"github.com/elastic/gosigar"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
var _ Limit = (*DynamicLimit)(nil)
|
||||
|
||||
func (l *DynamicLimit) GetMemoryLimit() int64 {
|
||||
var mem gosigar.Mem
|
||||
if err := mem.Get(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
limit := int64(float64(mem.ActualFree) * l.MemoryFraction)
|
||||
if limit < l.MinMemory {
|
||||
limit = l.MinMemory
|
||||
} else if limit > l.MaxMemory {
|
||||
limit = l.MaxMemory
|
||||
}
|
||||
|
||||
return limit
|
||||
}
|
||||
|
||||
// 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 {
|
||||
system := &DynamicLimit{
|
||||
MinMemory: minMemory,
|
||||
MaxMemory: maxMemory,
|
||||
MemoryFraction: memFraction,
|
||||
BaseLimit: DefaultSystemBaseLimit(),
|
||||
}
|
||||
transient := &DynamicLimit{
|
||||
MinMemory: minMemory / 16,
|
||||
MaxMemory: maxMemory / 16,
|
||||
MemoryFraction: memFraction / 16,
|
||||
BaseLimit: DefaultTransientBaseLimit(),
|
||||
}
|
||||
svc := &DynamicLimit{
|
||||
MinMemory: minMemory / 2,
|
||||
MaxMemory: maxMemory / 2,
|
||||
MemoryFraction: memFraction / 2,
|
||||
BaseLimit: DefaultServiceBaseLimit(),
|
||||
}
|
||||
proto := &DynamicLimit{
|
||||
MinMemory: minMemory / 4,
|
||||
MaxMemory: maxMemory / 4,
|
||||
MemoryFraction: memFraction / 4,
|
||||
BaseLimit: DefaultProtocolBaseLimit(),
|
||||
}
|
||||
peer := &DynamicLimit{
|
||||
MinMemory: minMemory / 16,
|
||||
MaxMemory: maxMemory / 16,
|
||||
MemoryFraction: memFraction / 16,
|
||||
BaseLimit: DefaultPeerBaseLimit(),
|
||||
}
|
||||
conn := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: ConnBaseLimit(),
|
||||
}
|
||||
stream := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: StreamBaseLimit(),
|
||||
}
|
||||
|
||||
return &BasicLimiter{
|
||||
SystemLimits: system,
|
||||
TransientLimits: transient,
|
||||
DefaultServiceLimits: svc,
|
||||
DefaultProtocolLimits: proto,
|
||||
DefaultPeerLimits: peer,
|
||||
ConnLimits: conn,
|
||||
StreamLimits: stream,
|
||||
}
|
||||
}
|
77
limit_static.go
Normal file
77
limit_static.go
Normal file
@ -0,0 +1,77 @@
|
||||
package rcmgr
|
||||
|
||||
import (
|
||||
"github.com/pbnjay/memory"
|
||||
)
|
||||
|
||||
// StaticLimit is a limit with static values.
|
||||
type StaticLimit struct {
|
||||
BaseLimit
|
||||
Memory int64
|
||||
}
|
||||
|
||||
var _ Limit = (*StaticLimit)(nil)
|
||||
|
||||
func (l *StaticLimit) GetMemoryLimit() int64 {
|
||||
return l.Memory
|
||||
}
|
||||
|
||||
// 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 := int64(float64(memory.TotalMemory()) * memFraction)
|
||||
switch {
|
||||
case memoryCap < minMemory:
|
||||
memoryCap = minMemory
|
||||
case memoryCap > maxMemory:
|
||||
memoryCap = maxMemory
|
||||
}
|
||||
return newDefaultStaticLimiter(memoryCap)
|
||||
}
|
||||
|
||||
// NewFixedLimiter creates a limiter with default base limits and a specified system memory cap.
|
||||
func NewFixedLimiter(memoryCap int64) *BasicLimiter {
|
||||
return newDefaultStaticLimiter(memoryCap)
|
||||
}
|
||||
|
||||
func newDefaultStaticLimiter(memoryCap int64) *BasicLimiter {
|
||||
system := &StaticLimit{
|
||||
Memory: memoryCap,
|
||||
BaseLimit: DefaultSystemBaseLimit(),
|
||||
}
|
||||
transient := &StaticLimit{
|
||||
Memory: memoryCap / 16,
|
||||
BaseLimit: DefaultTransientBaseLimit(),
|
||||
}
|
||||
svc := &StaticLimit{
|
||||
Memory: memoryCap / 2,
|
||||
BaseLimit: DefaultServiceBaseLimit(),
|
||||
}
|
||||
proto := &StaticLimit{
|
||||
Memory: memoryCap / 4,
|
||||
BaseLimit: DefaultProtocolBaseLimit(),
|
||||
}
|
||||
peer := &StaticLimit{
|
||||
Memory: memoryCap / 16,
|
||||
BaseLimit: DefaultPeerBaseLimit(),
|
||||
}
|
||||
conn := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: ConnBaseLimit(),
|
||||
}
|
||||
stream := &StaticLimit{
|
||||
Memory: 16 << 20,
|
||||
BaseLimit: StreamBaseLimit(),
|
||||
}
|
||||
|
||||
return &BasicLimiter{
|
||||
SystemLimits: system,
|
||||
TransientLimits: transient,
|
||||
DefaultServiceLimits: svc,
|
||||
DefaultProtocolLimits: proto,
|
||||
DefaultPeerLimits: peer,
|
||||
ConnLimits: conn,
|
||||
StreamLimits: stream,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user