diff --git a/limit.go b/limit.go index 0cda52b..c3a0deb 100644 --- a/limit.go +++ b/limit.go @@ -8,10 +8,27 @@ import ( // Limit is an object that specifies basic resource limits. type Limit interface { + // GetMemoryLimit returns the (current) memory limit. GetMemoryLimit() int64 + // GetStreamLimit returns the stream limit, for inbound or outbound streams. GetStreamLimit(network.Direction) int + // GetConnLimit returns the connection limit, for inbound or outbound connections. GetConnLimit(network.Direction) int + // GetFDLimit returns the file descriptor limit. GetFDLimit() int + + // WithMemoryLimit creates a copy of this limit object, with memory limit adjusted to + // the specified memFraction of its current value, bounded by minMemory and maxMemory. + WithMemoryLimit(memFraction float64, minMemory, maxMemory int64) Limit + // WithStreamLimit creates a copy of this limit object, with stream limits adjusted + // as specified. + WithStreamLimit(numStreamsIn, numStreamsOut int) Limit + // WithConnLimit creates a copy of this limit object, with connetion limits adjusted + // as specified. + WithConnLimit(numConnsIn, numConnsOut int) Limit + // WithFDLimit creates a copy of this limit object, with file descriptor limits adjusted + // as specified + WithFDLimit(numFD int) Limit } // Limiter is the interface for providing limits to the resource manager. diff --git a/limit_dynamic.go b/limit_dynamic.go index 99c849a..08ad934 100644 --- a/limit_dynamic.go +++ b/limit_dynamic.go @@ -38,6 +38,46 @@ func (l *DynamicLimit) GetMemoryLimit() int64 { return limit } +func (l *DynamicLimit) WithMemoryLimit(memFraction float64, minMemory, maxMemory int64) Limit { + r := new(DynamicLimit) + *r = *l + + r.MemoryFraction *= memFraction + r.MinMemory = minMemory + r.MaxMemory = maxMemory + + return r +} + +func (l *DynamicLimit) WithStreamLimit(numStreamsIn, numStreamsOut int) Limit { + r := new(DynamicLimit) + *r = *l + + r.BaseLimit.StreamsInbound = numStreamsIn + r.BaseLimit.StreamsOutbound = numStreamsOut + + return r +} + +func (l *DynamicLimit) WithConnLimit(numConnsIn, numConnsOut int) Limit { + r := new(DynamicLimit) + *r = *l + + r.BaseLimit.ConnsInbound = numConnsIn + r.BaseLimit.ConnsOutbound = numConnsOut + + return r +} + +func (l *DynamicLimit) WithFDLimit(numFD int) Limit { + r := new(DynamicLimit) + *r = *l + + r.BaseLimit.FD = numFD + + 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 diff --git a/limit_static.go b/limit_static.go index 7cf076a..8a1010e 100644 --- a/limit_static.go +++ b/limit_static.go @@ -16,6 +16,49 @@ func (l *StaticLimit) GetMemoryLimit() int64 { return l.Memory } +func (l *StaticLimit) WithMemoryLimit(memFraction float64, minMemory, maxMemory int64) Limit { + r := new(StaticLimit) + *r = *l + + r.Memory = int64(memFraction * float64(r.Memory)) + if r.Memory < minMemory { + r.Memory = minMemory + } else if r.Memory > maxMemory { + r.Memory = maxMemory + } + + return r +} + +func (l *StaticLimit) WithStreamLimit(numStreamsIn, numStreamsOut int) Limit { + r := new(StaticLimit) + *r = *l + + r.BaseLimit.StreamsInbound = numStreamsIn + r.BaseLimit.StreamsOutbound = numStreamsOut + + return r +} + +func (l *StaticLimit) WithConnLimit(numConnsIn, numConnsOut int) Limit { + r := new(StaticLimit) + *r = *l + + r.BaseLimit.ConnsInbound = numConnsIn + r.BaseLimit.ConnsOutbound = numConnsOut + + return r +} + +func (l *StaticLimit) WithFDLimit(numFD int) Limit { + r := new(StaticLimit) + *r = *l + + r.BaseLimit.FD = numFD + + 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.