go-libp2p-resource-manager/limit_dynamic.go

129 lines
3.3 KiB
Go
Raw Permalink Normal View History

2022-01-06 18:57:37 +08:00
package rcmgr
import (
2022-01-09 16:32:45 +08:00
"runtime"
"github.com/pbnjay/memory"
2022-01-06 18:57:37 +08:00
)
// DynamicLimit is a limit with dynamic memory values, based on available (free) memory
type DynamicLimit struct {
BaseLimit
MemoryLimit
2022-01-06 18:57:37 +08:00
}
var _ Limit = (*DynamicLimit)(nil)
func (l *DynamicLimit) GetMemoryLimit() int64 {
2022-01-09 16:32:45 +08:00
freemem := memory.FreeMemory()
// account for memory retained by the runtime that is actually free
// HeapInuse - HeapAlloc is the memory available in allocator spans
// HeapIdle - HeapReleased is memory held by the runtime that could be returned to the OS
var memstat runtime.MemStats
runtime.ReadMemStats(&memstat)
freemem += (memstat.HeapInuse - memstat.HeapAlloc) + (memstat.HeapIdle - memstat.HeapReleased)
return l.MemoryLimit.GetMemory(int64(freemem))
2022-01-06 18:57:37 +08:00
}
func (l *DynamicLimit) WithMemoryLimit(memFraction float64, minMemory, maxMemory int64) Limit {
r := new(DynamicLimit)
*r = *l
r.MemoryLimit.MemoryFraction *= memFraction
r.MemoryLimit.MinMemory = minMemory
r.MemoryLimit.MaxMemory = maxMemory
return r
}
2022-01-15 02:10:18 +08:00
func (l *DynamicLimit) WithStreamLimit(numStreamsIn, numStreamsOut, numStreams int) Limit {
r := new(DynamicLimit)
*r = *l
r.BaseLimit.StreamsInbound = numStreamsIn
r.BaseLimit.StreamsOutbound = numStreamsOut
2022-01-15 02:10:18 +08:00
r.BaseLimit.Streams = numStreams
return r
}
2022-01-15 02:10:18 +08:00
func (l *DynamicLimit) WithConnLimit(numConnsIn, numConnsOut, numConns int) Limit {
r := new(DynamicLimit)
*r = *l
r.BaseLimit.ConnsInbound = numConnsIn
r.BaseLimit.ConnsOutbound = numConnsOut
2022-01-15 02:10:18 +08:00
r.BaseLimit.Conns = numConns
return r
}
func (l *DynamicLimit) WithFDLimit(numFD int) Limit {
r := new(DynamicLimit)
*r = *l
r.BaseLimit.FD = numFD
return r
}
// NewDefaultDynamicLimiter creates a limiter with default limits and a memory cap
// dynamically computed based on available memory.
2022-01-17 17:17:11 +08:00
func NewDefaultDynamicLimiter(memFraction float64, minMemory, maxMemory int64) *BasicLimiter {
return NewDynamicLimiter(DefaultLimits.WithSystemMemory(memFraction, minMemory, maxMemory))
}
// NewDynamicLimiter crates a dynamic limiter with the specified defaults
func NewDynamicLimiter(cfg DefaultLimitConfig) *BasicLimiter {
2022-01-06 18:57:37 +08:00
system := &DynamicLimit{
MemoryLimit: cfg.SystemMemory,
BaseLimit: cfg.SystemBaseLimit,
2022-01-06 18:57:37 +08:00
}
transient := &DynamicLimit{
MemoryLimit: cfg.TransientMemory,
BaseLimit: cfg.TransientBaseLimit,
2022-01-06 18:57:37 +08:00
}
svc := &DynamicLimit{
MemoryLimit: cfg.ServiceMemory,
BaseLimit: cfg.ServiceBaseLimit,
2022-01-06 18:57:37 +08:00
}
svcPeer := &DynamicLimit{
MemoryLimit: cfg.ServicePeerMemory,
BaseLimit: cfg.ServicePeerBaseLimit,
}
2022-01-06 18:57:37 +08:00
proto := &DynamicLimit{
MemoryLimit: cfg.ProtocolMemory,
BaseLimit: cfg.ProtocolBaseLimit,
2022-01-06 18:57:37 +08:00
}
protoPeer := &DynamicLimit{
MemoryLimit: cfg.ProtocolPeerMemory,
BaseLimit: cfg.ProtocolPeerBaseLimit,
}
2022-01-06 18:57:37 +08:00
peer := &DynamicLimit{
MemoryLimit: cfg.PeerMemory,
BaseLimit: cfg.PeerBaseLimit,
2022-01-06 18:57:37 +08:00
}
conn := &StaticLimit{
Memory: cfg.ConnMemory,
BaseLimit: cfg.ConnBaseLimit,
2022-01-06 18:57:37 +08:00
}
stream := &StaticLimit{
Memory: cfg.StreamMemory,
BaseLimit: cfg.StreamBaseLimit,
2022-01-06 18:57:37 +08:00
}
return &BasicLimiter{
SystemLimits: system,
TransientLimits: transient,
DefaultServiceLimits: svc,
DefaultServicePeerLimits: svcPeer,
DefaultProtocolLimits: proto,
DefaultProtocolPeerLimits: protoPeer,
DefaultPeerLimits: peer,
ConnLimits: conn,
StreamLimits: stream,
2022-01-06 18:57:37 +08:00
}
}