Documentation ¶
Index ¶
- Constants
- Variables
- func GetServiceState(name string) string
- func GetSystemState() string
- type BaseLimit
- type Direction
- type ErrConnLimitExceeded
- type ErrMemoryLimitExceeded
- type Limit
- type LimitConfig
- type Limiter
- type NullResourceManager
- func (n *NullResourceManager) Close() error
- func (n *NullResourceManager) OpenService(svc string) (ResourceScope, error)
- func (n *NullResourceManager) ViewService(svc string, f func(ResourceScope) error) error
- func (n *NullResourceManager) ViewSystem(f func(ResourceScope) error) error
- func (n *NullResourceManager) ViewTransient(f func(ResourceScope) error) error
- type NullScope
- type ResourceManager
- type ResourceScope
- type ResourceScopeSpan
- type ResourceScopeViewer
- type ScopeStat
Constants ¶
const ( LimitFactor = 0.85 DefaultMemorySize uint64 = 8 * 1024 * 1024 )
const ( // ReservationPriorityLow is a reservation priority that indicates a reservation if the scope // memory utilization is at 40% or less. ReservationPriorityLow uint8 = 101 // ReservationPriorityMedium is a reservation priority that indicates a reservation if the scope // memory utilization is at 60% or less. ReservationPriorityMedium uint8 = 152 // ReservationPriorityHigh is a reservation priority that indicates a reservation if the scope // memory utilization is at 80% or less. ReservationPriorityHigh uint8 = 203 // ReservationPriorityAlways is a reservation priority that indicates a reservation if there is // enough memory, regardless of scope utilization. ReservationPriorityAlways uint8 = 255 )
Variables ¶
var DefaultLimitConfig = &LimitConfig{ SystemLimit: &InfiniteBaseLimit, Service: make(map[string]*BaseLimit), }
var ErrResourceLimitExceeded = errors.New("resource limit exceeded")
ErrResourceLimitExceeded is returned when attempting to perform an operation that would exceed system resource limits.
var ErrResourceScopeClosed = errors.New("resource scope closed")
ErrResourceScopeClosed is returned when attempting to reserve resources in a closed resource scope.
var InfiniteBaseLimit = BaseLimit{ Conns: math.MaxInt, ConnsInbound: math.MaxInt, ConnsOutbound: math.MaxInt, FD: math.MaxInt, Memory: math.MaxInt64, }
InfiniteBaseLimit are a limiter configuration that uses unlimited limits, thus effectively not limiting anything. Keep in mind that the operating system limits the number of file descriptors that an application can use.
Functions ¶
func GetServiceState ¶ added in v0.1.1
func GetSystemState ¶ added in v0.1.1
func GetSystemState() string
Types ¶
type BaseLimit ¶
type BaseLimit struct { Conns int `json:",omitempty"` ConnsInbound int `json:",omitempty"` ConnsOutbound int `json:",omitempty"` FD int `json:",omitempty"` Memory int64 `json:",omitempty"` }
BaseLimit is a mixin type for basic resource limits.
func (*BaseLimit) GetConnLimit ¶
GetConnLimit returns the connection limit, for inbound or outbound connections.
func (*BaseLimit) GetConnTotalLimit ¶
GetConnTotalLimit returns the total connection limit
func (*BaseLimit) GetFDLimit ¶
GetFDLimit returns the file descriptor limit.
func (*BaseLimit) GetMemoryLimit ¶
GetMemoryLimit returns the (current) memory limit.
type Direction ¶
type Direction int
Direction represents which peer in a stream initiated a connection.
type ErrConnLimitExceeded ¶
type ErrConnLimitExceeded struct {
// contains filtered or unexported fields
}
func (*ErrConnLimitExceeded) Error ¶
func (e *ErrConnLimitExceeded) Error() string
func (*ErrConnLimitExceeded) Unwrap ¶
func (e *ErrConnLimitExceeded) Unwrap() error
type ErrMemoryLimitExceeded ¶
type ErrMemoryLimitExceeded struct {
// contains filtered or unexported fields
}
func (*ErrMemoryLimitExceeded) Error ¶
func (e *ErrMemoryLimitExceeded) Error() string
func (*ErrMemoryLimitExceeded) Unwrap ¶
func (e *ErrMemoryLimitExceeded) Unwrap() error
type Limit ¶
type Limit interface { // GetMemoryLimit returns the (current) memory limit. GetMemoryLimit() int64 // GetConnLimit returns the connection limit, for inbound or outbound connections. GetConnLimit(Direction) int // GetConnTotalLimit returns the total connection limit GetConnTotalLimit() int // GetFDLimit returns the file descriptor limit. GetFDLimit() int // String returns the Limit state string String() string }
Limit is an interface that that specifies basic resource limits.
type LimitConfig ¶
func NewLimitConfigFromToml ¶
func NewLimitConfigFromToml(file string) (*LimitConfig, error)
func (*LimitConfig) GetServiceLimits ¶
func (cfg *LimitConfig) GetServiceLimits(svc string) Limit
func (*LimitConfig) GetSystemLimits ¶
func (cfg *LimitConfig) GetSystemLimits() Limit
func (*LimitConfig) GetTransientLimits ¶
func (cfg *LimitConfig) GetTransientLimits() Limit
func (*LimitConfig) String ¶
func (cfg *LimitConfig) String() string
type Limiter ¶
type Limiter interface { GetSystemLimits() Limit GetTransientLimits() Limit GetServiceLimits(svc string) Limit String() string }
Limiter is an interface for providing limits to the resource manager.
type NullResourceManager ¶
type NullResourceManager struct{}
NullResourceManager is a stub for tests and initialization of default values
func (*NullResourceManager) Close ¶
func (n *NullResourceManager) Close() error
func (*NullResourceManager) OpenService ¶
func (n *NullResourceManager) OpenService(svc string) (ResourceScope, error)
func (*NullResourceManager) ViewService ¶
func (n *NullResourceManager) ViewService(svc string, f func(ResourceScope) error) error
func (*NullResourceManager) ViewSystem ¶
func (n *NullResourceManager) ViewSystem(f func(ResourceScope) error) error
func (*NullResourceManager) ViewTransient ¶
func (n *NullResourceManager) ViewTransient(f func(ResourceScope) error) error
type NullScope ¶
type NullScope struct{}
NullScope is a stub for tests and initialization of default values
func (*NullScope) BeginSpan ¶
func (n *NullScope) BeginSpan() (ResourceScopeSpan, error)
func (*NullScope) ReleaseMemory ¶
type ResourceManager ¶
type ResourceManager interface { ResourceScopeViewer // OpenService creates a new Service scope associated with System/Transient Scope // The caller owns the returned scope and is responsible for calling Done in order // to signify the end of the scope's span. OpenService(svc string) (ResourceScope, error) // Close closes the resource manager Close() error }
ResourceManager is the interface to the resource management subsystem. The ResourceManager tracks and accounts for resource usage in the stack, from the internals to the application, and provides a mechanism to limit resource usage according to a user configurable policy.
Resource Management through the ResourceManager is based on the concept of Resource Management Scopes, whereby resource usage is constrained by a DAG of scopes, The following diagram illustrates the structure of the resource constraint DAG: System
+------------> Transient............+................+ | . . +------------> Service------------- . ----------+ . | . | . +---> Connection--- . ----------+ .
The basic resources accounted by the ResourceManager include memory, connections, and file descriptors. These account for both space and time used by the stack, as each resource has a direct effect on the system availability and performance.
The modus operandi of the resource manager is to restrict resource usage at the time of reservation. When a component of the stack needs to use a resource, it reserves it in the appropriate scope. The resource manager gates the reservation against the scope applicable limits; if the limit is exceeded, then an error is up the component to act accordingly. At the lower levels of the stack, this will normally signal a failure of some sorts, like failing to opening a connection, which will propagate to the programmer. Some components may be able to handle resource reservation failure more gracefully. All resources reserved in some scopes are released when the scope is closed. For low level scopes, mainly Service and Connection scopes, this happens when the service or connection is closed.
Service programmers will typically use the resource manager to reserve memory for their subsystem. This happens with two avenues: the programmer can attach a connection to a service, whereby resources reserved by the connection are automatically accounted in the service budget; or the programmer may directly interact with the service scope, by using ViewService through the resource manager interface.
Application programmers can also directly reserve memory in some applicable scope. In order to facilitate control flow delimited resource accounting, all scopes defined in the system allow for the user to create spans. Spans are temporary scopes rooted at some other scope and release their resources when the programmer is done with them. Span scopes can form trees, with nested spans.
Typical Usage:
- Low level components of the system all have access to the resource manager and create connection scopes through it. These scopes are accessible to the user, albeit with a narrower interface, through Conn objects who have a Scope method.
- Services typically center around connections, where the programmer can attach connections to a particular service. They can also directly reserve memory for a service by accessing the service scope using the ResourceManager interface.
- Applications that want to account for their resource usage can reserve memory, typically using a span, directly in the System or a Service scope.
func NewResourceManager ¶
func NewResourceManager(limits Limiter) (ResourceManager, error)
NewResourceManager inits and returns singleton instance of ResourceManager
func ResrcManager ¶
func ResrcManager() ResourceManager
ResrcManager return the global singleton instance of ResourceManager
type ResourceScope ¶
type ResourceScope interface { // ReserveMemory reserves memory/buffer space in the scope; the unit is bytes. // // If ReserveMemory returns an error, then no memory was reserved and the caller // should handle the failure condition. // // The priority argument indicates the priority of the memory reservation. A reservation // will fail if the available memory is less than (1+prio)/256 of the scope limit, providing // a mechanism to gracefully handle optional reservations that might overload the system. // // There are 4 predefined priority levels, Low, Medium, High and Always, capturing common // patterns, but the user is free to use any granularity applicable to his case. ReserveMemory(size int, prio uint8) error // ReleaseMemory explicitly releases memory previously reserved with ReserveMemory ReleaseMemory(size int) // Stat retrieves current resource usage for the scope. Stat() ScopeStat // Name returns the name of this scope Name() string // BeginSpan creates a new span scope rooted at this scope BeginSpan() (ResourceScopeSpan, error) // Release resource at this scope Release() }
ResourceScope is the interface for all scopes.
type ResourceScopeSpan ¶
type ResourceScopeSpan interface { ResourceScope // Done ends the span and releases associated resources. Done() }
ResourceScopeSpan is a ResourceScope with a delimited span. Span scopes are control flow delimited and release all their associated resources when the programmer calls Done.
Example:
s, err := someScope.BeginSpan() if err != nil { ... } defer s.Done() if err := s.ReserveMemory(...); err != nil { ... } // ... use memory
type ResourceScopeViewer ¶
type ResourceScopeViewer interface { // ViewSystem views the system wide resource scope. // The system scope is the top level scope that accounts for global // resource usage at all levels of the system. This scope constrains all // other scopes and institutes global hard limits. ViewSystem(func(ResourceScope) error) error // ViewTransient views the transient (DMZ) resource scope. // The transient scope accounts for resources that are in the process of // full establishment. For instance, a new connection prior to the // handshake does not belong to any service, but it still needs to be // constrained as this opens an avenue for attacks in transient resource // usage. ViewTransient(func(ResourceScope) error) error // ViewService retrieves a service-specific scope. ViewService(string, func(ResourceScope) error) error }
ResourceScopeViewer is a mixin interface providing view methods for accessing top level scopes