forked from TrueCloudLab/frostfs-node
130 lines
2.8 KiB
Go
130 lines
2.8 KiB
Go
package limits
|
|
|
|
import (
|
|
"math"
|
|
"strconv"
|
|
"time"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
|
"github.com/spf13/cast"
|
|
)
|
|
|
|
const (
|
|
NoLimit int64 = math.MaxInt64
|
|
DefaultIdleTimeout = 5 * time.Minute
|
|
)
|
|
|
|
// From wraps config section into Config.
|
|
func From(c *config.Config) *Config {
|
|
return (*Config)(c)
|
|
}
|
|
|
|
// Config is a wrapper over the config section
|
|
// which provides access to Shard's limits configurations.
|
|
type Config config.Config
|
|
|
|
// Read returns the value of "read" limits config section.
|
|
func (x *Config) Read() OpConfig {
|
|
return x.parse("read")
|
|
}
|
|
|
|
// Write returns the value of "write" limits config section.
|
|
func (x *Config) Write() OpConfig {
|
|
return x.parse("write")
|
|
}
|
|
|
|
func (x *Config) parse(sub string) OpConfig {
|
|
c := (*config.Config)(x).Sub(sub)
|
|
var result OpConfig
|
|
|
|
if s := config.Int(c, "max_waiting_ops"); s > 0 {
|
|
result.MaxWaitingOps = s
|
|
} else {
|
|
result.MaxWaitingOps = NoLimit
|
|
}
|
|
|
|
if s := config.Int(c, "max_running_ops"); s > 0 {
|
|
result.MaxRunningOps = s
|
|
} else {
|
|
result.MaxRunningOps = NoLimit
|
|
}
|
|
|
|
if s := config.DurationSafe(c, "idle_timeout"); s > 0 {
|
|
result.IdleTimeout = s
|
|
} else {
|
|
result.IdleTimeout = DefaultIdleTimeout
|
|
}
|
|
|
|
result.Tags = tags(c)
|
|
|
|
return result
|
|
}
|
|
|
|
type OpConfig struct {
|
|
// MaxWaitingOps returns the value of "max_waiting_ops" config parameter.
|
|
//
|
|
// Equals NoLimit if the value is not a positive number.
|
|
MaxWaitingOps int64
|
|
// MaxRunningOps returns the value of "max_running_ops" config parameter.
|
|
//
|
|
// Equals NoLimit if the value is not a positive number.
|
|
MaxRunningOps int64
|
|
// IdleTimeout returns the value of "idle_timeout" config parameter.
|
|
//
|
|
// Equals DefaultIdleTimeout if the value is not a valid duration.
|
|
IdleTimeout time.Duration
|
|
// Tags returns the value of "tags" config parameter.
|
|
//
|
|
// Equals nil if the value is not a valid tags config slice.
|
|
Tags []IOTagConfig
|
|
}
|
|
|
|
type IOTagConfig struct {
|
|
Tag string
|
|
Weight *float64
|
|
LimitOps *float64
|
|
ReservedOps *float64
|
|
}
|
|
|
|
func tags(c *config.Config) []IOTagConfig {
|
|
c = c.Sub("tags")
|
|
var result []IOTagConfig
|
|
for i := 0; ; i++ {
|
|
tag := config.String(c, strconv.Itoa(i)+".tag")
|
|
if tag == "" {
|
|
return result
|
|
}
|
|
|
|
var tagConfig IOTagConfig
|
|
tagConfig.Tag = tag
|
|
|
|
v := c.Value(strconv.Itoa(i) + ".weight")
|
|
if v != nil {
|
|
w, err := cast.ToFloat64E(v)
|
|
panicOnErr(err)
|
|
tagConfig.Weight = &w
|
|
}
|
|
|
|
v = c.Value(strconv.Itoa(i) + ".limit_ops")
|
|
if v != nil {
|
|
l, err := cast.ToFloat64E(v)
|
|
panicOnErr(err)
|
|
tagConfig.LimitOps = &l
|
|
}
|
|
|
|
v = c.Value(strconv.Itoa(i) + ".reserved_ops")
|
|
if v != nil {
|
|
r, err := cast.ToFloat64E(v)
|
|
panicOnErr(err)
|
|
tagConfig.ReservedOps = &r
|
|
}
|
|
|
|
result = append(result, tagConfig)
|
|
}
|
|
}
|
|
|
|
func panicOnErr(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|