protection

package
v5.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetResourceProtectionType

func GetResourceProtectionType(err error) string

GetResourceProtectionType returns the type of resource protection error

func IsResourceProtectionError

func IsResourceProtectionError(err error) bool

IsResourceProtectionError checks if an error is a resource protection error

Types

type BatchLimiter

type BatchLimiter struct {
	// contains filtered or unexported fields
}

BatchLimiter provides batch operation protection

func (*BatchLimiter) AcquireBatch

func (bl *BatchLimiter) AcquireBatch(ctx context.Context, batchSize int) error

AcquireBatch acquires permission for a batch operation

func (*BatchLimiter) ReleaseBatch

func (bl *BatchLimiter) ReleaseBatch()

ReleaseBatch releases batch operation permission

type MemoryAlert

type MemoryAlert struct {
	Timestamp    time.Time `json:"timestamp"`
	Type         string    `json:"type"`
	Severity     string    `json:"severity"`
	CurrentMB    int64     `json:"current_mb"`
	LimitMB      int64     `json:"limit_mb"`
	UsagePercent float64   `json:"usage_percent"`
}

MemoryAlert represents a memory usage alert

type MemoryMonitor

type MemoryMonitor struct {
	// contains filtered or unexported fields
}

MemoryMonitor samples memory usage on demand.

It owns no goroutine and no timer: a caller invokes Sample (directly or through ResourceProtector.SampleMemory) inside the work it wants measured — normally a request or handler invocation. On-demand sampling is the only shape that fits a Lambda execution environment, which is frozen the moment a handler returns; a background sampling loop would either be frozen mid-flight or, if started during module initialization, resume against an invocation that is already over.

func (*MemoryMonitor) Sample

func (mm *MemoryMonitor) Sample()

Sample records current memory usage on demand: it reads the runtime's memory statistics, updates the peak, and, when usage is at or above the configured panic threshold, records an alert, invokes the alert callback, and forces a garbage collection. It is the whole of this type's behavior: no goroutine and no timer are involved.

type ProtectionError

type ProtectionError struct {
	Type   string `json:"type"`
	Detail string `json:"detail"`
}

ProtectionError represents a resource protection error

func (*ProtectionError) Error

func (e *ProtectionError) Error() string

type ResourceLimits

type ResourceLimits struct {
	// HTTP request limits
	MaxRequestBodySize int64         `json:"max_request_body_size" yaml:"max_request_body_size"`
	MaxRequestTimeout  time.Duration `json:"max_request_timeout" yaml:"max_request_timeout"`
	MaxConcurrentReq   int           `json:"max_concurrent_requests" yaml:"max_concurrent_requests"`

	// Batch operation limits
	MaxBatchSize       int     `json:"max_batch_size" yaml:"max_batch_size"`
	MaxConcurrentBatch int     `json:"max_concurrent_batch" yaml:"max_concurrent_batch"`
	BatchRateLimit     float64 `json:"batch_rate_limit" yaml:"batch_rate_limit"`

	// Memory limits. Memory is sampled on demand (see
	// ResourceProtector.SampleMemory), so there is no check interval.
	MaxMemoryMB          int64   `json:"max_memory_mb" yaml:"max_memory_mb"`
	MemoryPanicThreshold float64 `json:"memory_panic_threshold" yaml:"memory_panic_threshold"`

	// Rate limiting
	RequestsPerSecond float64 `json:"requests_per_second" yaml:"requests_per_second"`
	BurstSize         int     `json:"burst_size" yaml:"burst_size"`
}

ResourceLimits defines configurable resource limits

func DefaultResourceLimits

func DefaultResourceLimits() ResourceLimits

DefaultResourceLimits returns secure default limits

type ResourceProtector

type ResourceProtector struct {
	// contains filtered or unexported fields
}

ResourceProtector provides resource protection and monitoring

func NewResourceProtector

func NewResourceProtector(config ResourceLimits) *ResourceProtector

NewResourceProtector creates a new resource protector

func (*ResourceProtector) GetBatchLimiter

func (rp *ResourceProtector) GetBatchLimiter() *BatchLimiter

GetBatchLimiter returns a batch limiter

func (*ResourceProtector) GetStats

func (rp *ResourceProtector) GetStats() ResourceStats

GetStats returns current resource usage statistics

func (*ResourceProtector) HealthCheck

func (rp *ResourceProtector) HealthCheck() map[string]any

HealthCheck performs a resource protection health check

func (*ResourceProtector) SampleMemory

func (rp *ResourceProtector) SampleMemory()

SampleMemory samples current memory usage on demand, updating the protector's memory statistics and invoking the alert callback when the configured threshold is crossed. It is synchronous: it returns only after the sample has been recorded, and it starts nothing that could run after the caller returns. Call it inside a request to have the request's memory use recorded; there is no background sampler.

func (*ResourceProtector) SecureBodyReader

func (rp *ResourceProtector) SecureBodyReader(r *http.Request) ([]byte, error)

SecureBodyReader reads an HTTP request body under a byte-size limit, a per-request wall-clock timeout, and the protector's shared concurrency and rate limits.

It holds one request-concurrency slot while it reads the body, and releases that slot no later than MaxRequestTimeout. On timeout the slot is released before the body cleanup runs, so a client that declares a body and withholds it cannot keep a slot past the timeout: the timeout path still closes the body and joins its reader, but neither of those blocking operations may extend the slot's lifetime. With the previous in-order release they did keep the slot until the client disconnected, and MaxConcurrentReq stalled connections rejected every other request.

The trade-off is explicit. Go's HTTP/1 request body can block both Read and Close on the same stalled socket, so on timeout this call — and the handler goroutine running it — can stay blocked until the client disconnects or a transport deadline fires; the reader goroutine is joined rather than abandoned, so nothing outlives the call, but the call itself does not return at the timeout. Lambda freezes the execution environment when the handler returns; here the handler does not return, so the stalled invocation is held until it times out while the shared concurrency slot is already free. An application that serves live HTTP/1 requests through this helper should impose a server- or upstream-level body-read deadline (for example net/http's Server.ReadTimeout) so the read ends before this last-resort path is reached.

func (*ResourceProtector) SetMemoryAlertCallback

func (rp *ResourceProtector) SetMemoryAlertCallback(alertCallback func(MemoryAlert))

SetMemoryAlertCallback sets the callback invoked when a sample crosses the configured memory threshold. The callback runs on whichever goroutine called Sample; it is called synchronously, inside the work that requested the sample, so it never outlives the invocation that triggered it.

type ResourceStats

type ResourceStats struct {
	LastStatsUpdate    time.Time `json:"last_stats_update"`
	ConcurrentBatchOps int64     `json:"concurrent_batch_operations"`
	ConcurrentRequests int64     `json:"concurrent_requests"`
	MaxConcurrentReq   int64     `json:"max_concurrent_requests"`
	TotalBatchOps      int64     `json:"total_batch_operations"`
	RejectedBatchOps   int64     `json:"rejected_batch_operations"`
	TotalRequests      int64     `json:"total_requests"`
	MaxConcurrentBatch int64     `json:"max_concurrent_batch"`
	CurrentMemoryMB    int64     `json:"current_memory_mb"`
	PeakMemoryMB       int64     `json:"peak_memory_mb"`
	MemoryAlerts       int64     `json:"memory_alerts"`
	RateLimitHits      int64     `json:"rate_limit_hits"`
	RejectedRequests   int64     `json:"rejected_requests"`
}

ResourceStats tracks resource usage statistics

type SimpleLimiter

type SimpleLimiter struct {
	// contains filtered or unexported fields
}

SimpleLimiter is a basic rate limiter implementation

func NewSimpleLimiter

func NewSimpleLimiter(rps float64, burst int) *SimpleLimiter

NewSimpleLimiter creates a new simple rate limiter

func (*SimpleLimiter) Allow

func (l *SimpleLimiter) Allow() bool

Allow checks if a request is allowed

Jump to

Keyboard shortcuts

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