cache: Per-client fair-share bandwidth on table uplink
CI / vulncheck (pull_request) Successful in 20s
CI / check-and-test (pull_request) Failing after 21s

This commit is contained in:
2026-09-09 20:22:23 +00:00
parent 50ca0a071c
commit b7710de0ca
13 changed files with 439 additions and 18 deletions
+13
View File
@@ -19,6 +19,11 @@ type Config struct {
MaxConcurrentRequests int64 `yaml:"max_concurrent_requests" default:"200"`
MaxRequestsPerClient int64 `yaml:"max_requests_per_client" default:"5"`
// Table-tier uplink bandwidth shaping (bytes/sec). Distinct from MaxRequestsPerClient.
// Empty/"0" uplink and 0 max_bytes_per_client_per_sec = disabled (current unlimited behavior).
UplinkBandwidth string `yaml:"uplink_bandwidth"` // e.g. "10MB" via go-units = bytes/sec
MaxBytesPerClientPerSec int64 `yaml:"max_bytes_per_client_per_sec"` // absolute per-client cap; 0 = none
// Hardening limits (security/correctness)
MaxObjectSize string `yaml:"max_object_size" default:"0"` // 0=unlimited; e.g. "256MB" protects against OOM from huge/malicious upstream responses
TrustedProxies []string `yaml:"trusted_proxies"` // CIDR list; empty=never trust X-Forwarded-For (safe default). See README security notes.
@@ -186,6 +191,14 @@ func (c Config) Validate() error {
if c.MaxRequestsPerClient < 0 {
return fmt.Errorf("negative per-client limit not allowed")
}
if c.MaxBytesPerClientPerSec < 0 {
return fmt.Errorf("negative max_bytes_per_client_per_sec not allowed")
}
if c.UplinkBandwidth != "" && c.UplinkBandwidth != "0" {
if _, err := units.FromHumanSize(c.UplinkBandwidth); err != nil {
return fmt.Errorf("invalid uplink_bandwidth: %w", err)
}
}
if c.Cache.Memory.GCAlgorithm != "" {
switch c.Cache.Memory.GCAlgorithm {