rcmgr

package
v0.2.3-test.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2023 License: GPL-3.0 Imports: 2 Imported by: 0

README

ResourceManager

ResourceManager interface manages resources within SP system, tracking and accounting for usage across the stack, from internal components to applications. It also allows for resource usage to be limited based on user-configurable policies.

Concept

Limit

The module 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.

The Limit is configured by the user policy. supports MemoryLimit,ConnectionsLimit, FDLimit(file descriptor limit), TaskLimit. The MemoryLimit limits maximum memory for a component reservation. The ConnectionsLimit limits maximum connections number for a component reservation, includes inbound and outbound connections. The FDLimitlimits maximum fd number for a component reservation, includes the open of sockets and files.

The TaskLimit is unique to SP. Task is the smallest unit of SP internal component interaction. Each component can limit the number of tasks executed. Tasks are divided into high, medium and low priorities, the priority can be used as an important basis for task scheduling within SP. The higher the priority, the faster it is expected to be executed, and the resources will be assigned priority for execution, such as seal object. The lower the priority, it can be executed later, and the resource requirements are not so urgent, such as delayed deletion.

Scope

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(Topmost Scope)

	+------------> Transient(Scope)........................+................+
	|                                                      .                .
	+------------> Service(Scope)------------------------- . ----------+    .
	|                                                      .           |    .
			   	   +--->  Connection/Memory/Task---------- . ----------+    .

Scope is an important node in DAG, Scope has children and siblings scopes. There is a directed edge between them. The children scopes share the limit of the parent scope, the child scope reserves the resources, the parent scope will reduce the corresponding amount of resources. Sibling scopes also have directionality, for example Service A Scope depends on(points to) System Scope, Service A reserves the resources, the System Scope will reduce the corresponding amount of resources. On the contrary, if the System Scope reserves resources, it will not affect Service A.

Example

    rcmgr := &ResourceManager{}
    serviceScope, err := rcmgr.OpenService(...)
	if err != nil { ... }
    defer scope.Close()
	
    s, err := serviceScope.BeginSpan()
	if err != nil { ... }
	defer s.Done()

	if err := s.ReserveMemory(...); err != nil { ... }
	// ... use memory

Documentation

Index

Constants

View Source
const (
	MaxLimitInt64 = math.MaxInt64
	MaxLimitInt   = math.MaxInt
)
View Source
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

This section is empty.

Functions

This section is empty.

Types

type Direction

type Direction int

Direction represents which peer in a stream initiated a connection.

const (
	// DirUnknown is the default direction.
	DirUnknown Direction = iota
	// DirInbound is for when the remote peer initiated a connection.
	DirInbound
	// DirOutbound is for when the local peer initiated a connection.
	DirOutbound
)

type Limit

type Limit interface {
	// GetMemoryLimit returns the (current) memory limit.
	GetMemoryLimit() int64
	// GetFDLimit returns the file descriptor limit.
	GetFDLimit() int
	// GetConnLimit returns the connection limit, for inbound or outbound connections.
	GetConnLimit(Direction) int
	// GetConnTotalLimit returns the total connection limit.
	GetConnTotalLimit() int
	// GetTaskLimit returns the task limit, for high, medium and low priority tasks.
	GetTaskLimit(ReserveTaskPriority) int
	// GetTaskTotalLimit returns the total task limit.
	GetTaskTotalLimit() int
	ScopeStat() *ScopeStat
	// NotLess returns an indicator whether cover the param limit fields.
	NotLess(Limit) bool
	// Add params limits fields value to self.
	Add(Limit)
	// Sub params limits fields value to self.
	Sub(Limit) bool
	// Equal returns an indicator whether equal the param limit.
	Equal(Limit) bool
	// String returns the Limit state string.
	String() string
}

Limit is an interface that that specifies basic resource limits.

type Limiter

type Limiter interface {
	// GetSystemLimits returns the system limits.
	GetSystemLimits() Limit
	// GetTransientLimits returns the transient limits.
	GetTransientLimits() Limit
	// GetServiceLimits returns a service-specific limits.
	GetServiceLimits(svc string) Limit
	// String returns the all kinds of Limit state string
	String() string
}

Limiter is an interface for providing limits to the resource manager.

type NullLimit

type NullLimit struct{}

NullLimit is a stub for tests and initialization of default values

func (*NullLimit) Add

func (n *NullLimit) Add(Limit)

func (*NullLimit) Equal

func (n *NullLimit) Equal(Limit) bool

func (*NullLimit) GetConnLimit

func (n *NullLimit) GetConnLimit(Direction) int

func (*NullLimit) GetConnTotalLimit

func (n *NullLimit) GetConnTotalLimit() int

func (*NullLimit) GetFDLimit

func (n *NullLimit) GetFDLimit() int

func (*NullLimit) GetMemoryLimit

func (n *NullLimit) GetMemoryLimit() int64

func (*NullLimit) GetServiceLimits

func (n *NullLimit) GetServiceLimits(svc string) Limit

func (*NullLimit) GetSystemLimits

func (n *NullLimit) GetSystemLimits() Limit

func (*NullLimit) GetTaskLimit

func (n *NullLimit) GetTaskLimit(ReserveTaskPriority) int

func (*NullLimit) GetTaskTotalLimit

func (n *NullLimit) GetTaskTotalLimit() int

func (*NullLimit) GetTransientLimits

func (n *NullLimit) GetTransientLimits() Limit

func (*NullLimit) NotLess

func (n *NullLimit) NotLess(Limit) bool

func (*NullLimit) ScopeStat

func (n *NullLimit) ScopeStat() *ScopeStat

func (*NullLimit) String

func (n *NullLimit) String() string

func (*NullLimit) Sub

func (n *NullLimit) Sub(Limit) bool

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) ServiceLimitString

func (n *NullResourceManager) ServiceLimitString(string, func(ResourceScope) string) string

func (*NullResourceManager) ServiceState

func (n *NullResourceManager) ServiceState(string) string

func (*NullResourceManager) SystemLimitString

func (n *NullResourceManager) SystemLimitString(func(ResourceScope) string) string

func (*NullResourceManager) SystemState

func (n *NullResourceManager) SystemState() string

func (*NullResourceManager) TransientLimitString

func (n *NullResourceManager) TransientLimitString(func(ResourceScope) string) string

func (*NullResourceManager) TransientState

func (n *NullResourceManager) TransientState() string

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) AddConn

func (n *NullScope) AddConn(dir Direction) error

func (*NullScope) AddTask

func (n *NullScope) AddTask(num int, prio ReserveTaskPriority) error

func (*NullScope) BeginSpan

func (n *NullScope) BeginSpan() (ResourceScopeSpan, error)

func (*NullScope) Done

func (n *NullScope) Done()

func (*NullScope) Name

func (n *NullScope) Name() string

func (*NullScope) Release

func (n *NullScope) Release()

func (*NullScope) ReleaseMemory

func (n *NullScope) ReleaseMemory(size int64)

func (*NullScope) RemainingResource

func (n *NullScope) RemainingResource() (Limit, error)

func (*NullScope) RemoveConn

func (n *NullScope) RemoveConn(dir Direction)

func (*NullScope) RemoveTask

func (n *NullScope) RemoveTask(num int, prio ReserveTaskPriority)

func (*NullScope) ReserveMemory

func (n *NullScope) ReserveMemory(size int64, prio uint8) error

func (*NullScope) ReserveResources

func (n *NullScope) ReserveResources(st *ScopeStat) error

func (*NullScope) Stat

func (n *NullScope) Stat() ScopeStat

type ReserveTaskPriority

type ReserveTaskPriority int

ReserveTaskPriority represents which priority in a reservation of task.

const (
	// ReserveTaskPriorityUnknown is the default task priority.
	ReserveTaskPriorityUnknown ReserveTaskPriority = iota
	// ReserveTaskPriorityHigh is a task reservation priority that indicates a
	// reservation consume a high task limit.
	ReserveTaskPriorityHigh
	// ReserveTaskPriorityMedium is a task reservation priority that indicates a
	// reservation consume a medium task limit.
	ReserveTaskPriorityMedium
	// ReserveTaskPriorityLow is a task reservation priority that indicates a
	// reservation consume a low task limit.
	ReserveTaskPriorityLow
)

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/Memory/Task--- . ----------+    .

The basic resources accounted by the ResourceManager include memory, connections, file descriptors and task. 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 module 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.

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 int64, prio uint8) error
	// ReleaseMemory explicitly releases memory previously reserved with ReserveMemory
	ReleaseMemory(size int64)
	// AddTask reserves task by ReserveTaskPriority in the scope.
	//
	// If ReserveTask returns an error, then no task quota was reserved and the caller
	// should handle the failure condition.
	AddTask(num int, prio ReserveTaskPriority) error
	// RemoveTask explicitly releases task reserved with AddTask.
	RemoveTask(num int, prio ReserveTaskPriority)
	// AddConn reserves connection by Direction in the scope.
	AddConn(dir Direction) error
	// RemoveConn explicitly releases connection reserved with AddConn.
	RemoveConn(dir Direction)
	// ReserveResources reserves the resource by ScopeStat, it will reserve all kinds
	// of resources atomic
	ReserveResources(st *ScopeStat) error
	// RemainingResource returns the remaining resource that have not be reserved
	RemainingResource() (Limit, error)
	// 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
	// SystemState output the system resource scope and limit readable
	SystemState() string
	// TransientState output the transient (DMZ)  resource scope and limit readable
	TransientState() string
	// ServiceState output a service-specific resource scope and limit readable
	ServiceState(string) string
}

ResourceScopeViewer is a mixin interface providing view methods for accessing top level scopes

type ScopeStat

type ScopeStat struct {
	Memory           int64
	NumTasksHigh     int64
	NumTasksMedium   int64
	NumTasksLow      int64
	NumConnsInbound  int64
	NumConnsOutbound int64
	NumFD            int64
}

ScopeStat is a struct containing resource accounting information.

func (ScopeStat) String

func (s ScopeStat) String() string

String returns the state string of ScopeStat TODO:: supports connections and fd field

type Unlimited

type Unlimited struct{}

func (*Unlimited) Add

func (n *Unlimited) Add(Limit)

func (*Unlimited) Equal

func (n *Unlimited) Equal(Limit) bool

func (*Unlimited) GetConnLimit

func (n *Unlimited) GetConnLimit(Direction) int

func (*Unlimited) GetConnTotalLimit

func (n *Unlimited) GetConnTotalLimit() int

func (*Unlimited) GetFDLimit

func (n *Unlimited) GetFDLimit() int

func (*Unlimited) GetMemoryLimit

func (n *Unlimited) GetMemoryLimit() int64

func (*Unlimited) GetServiceLimits

func (n *Unlimited) GetServiceLimits(svc string) Limit

func (*Unlimited) GetSystemLimits

func (n *Unlimited) GetSystemLimits() Limit

func (*Unlimited) GetTaskLimit

func (n *Unlimited) GetTaskLimit(ReserveTaskPriority) int

func (*Unlimited) GetTaskTotalLimit

func (n *Unlimited) GetTaskTotalLimit() int

func (*Unlimited) GetTransientLimits

func (n *Unlimited) GetTransientLimits() Limit

func (*Unlimited) NotLess

func (n *Unlimited) NotLess(Limit) bool

func (*Unlimited) ScopeStat

func (n *Unlimited) ScopeStat() *ScopeStat

func (*Unlimited) String

func (n *Unlimited) String() string

func (*Unlimited) Sub

func (n *Unlimited) Sub(Limit) bool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL