- Introduced maxConcurrentRequests and maxRequestsPerClient fields in the Config struct to manage request limits. - Updated the SteamCache implementation to utilize these new configuration options for controlling concurrent requests. - Enhanced the ServeHTTP method to enforce global and per-client rate limiting using semaphores. - Modified the root command to accept new flags for configuring concurrency limits via command-line arguments. - Updated tests to reflect changes in the SteamCache initialization and request handling logic.
129 lines
3.2 KiB
Go
129 lines
3.2 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type Config struct {
|
|
// Server configuration
|
|
ListenAddress string `yaml:"listen_address" default:":80"`
|
|
|
|
// Concurrency limits
|
|
MaxConcurrentRequests int64 `yaml:"max_concurrent_requests" default:"200"`
|
|
MaxRequestsPerClient int64 `yaml:"max_requests_per_client" default:"5"`
|
|
|
|
// Cache configuration
|
|
Cache CacheConfig `yaml:"cache"`
|
|
|
|
// Upstream configuration
|
|
Upstream string `yaml:"upstream"`
|
|
}
|
|
|
|
type CacheConfig struct {
|
|
// Memory cache settings
|
|
Memory MemoryConfig `yaml:"memory"`
|
|
|
|
// Disk cache settings
|
|
Disk DiskConfig `yaml:"disk"`
|
|
}
|
|
|
|
type MemoryConfig struct {
|
|
// Size of memory cache (e.g., "512MB", "1GB")
|
|
Size string `yaml:"size" default:"0"`
|
|
|
|
// Garbage collection algorithm: lru, lfu, fifo, largest, smallest, hybrid
|
|
GCAlgorithm string `yaml:"gc_algorithm" default:"lru"`
|
|
}
|
|
|
|
type DiskConfig struct {
|
|
// Size of disk cache (e.g., "10GB", "50GB")
|
|
Size string `yaml:"size" default:"0"`
|
|
|
|
// Path to disk cache directory
|
|
Path string `yaml:"path" default:""`
|
|
|
|
// Garbage collection algorithm: lru, lfu, fifo, largest, smallest, hybrid
|
|
GCAlgorithm string `yaml:"gc_algorithm" default:"lru"`
|
|
}
|
|
|
|
// LoadConfig loads configuration from a YAML file
|
|
func LoadConfig(configPath string) (*Config, error) {
|
|
if configPath == "" {
|
|
configPath = "config.yaml"
|
|
}
|
|
|
|
data, err := os.ReadFile(configPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read config file %s: %w", configPath, err)
|
|
}
|
|
|
|
var config Config
|
|
if err := yaml.Unmarshal(data, &config); err != nil {
|
|
return nil, fmt.Errorf("failed to parse config file %s: %w", configPath, err)
|
|
}
|
|
|
|
// Set defaults for empty values
|
|
if config.ListenAddress == "" {
|
|
config.ListenAddress = ":80"
|
|
}
|
|
if config.MaxConcurrentRequests == 0 {
|
|
config.MaxConcurrentRequests = 50
|
|
}
|
|
if config.MaxRequestsPerClient == 0 {
|
|
config.MaxRequestsPerClient = 3
|
|
}
|
|
if config.Cache.Memory.Size == "" {
|
|
config.Cache.Memory.Size = "0"
|
|
}
|
|
if config.Cache.Memory.GCAlgorithm == "" {
|
|
config.Cache.Memory.GCAlgorithm = "lru"
|
|
}
|
|
if config.Cache.Disk.Size == "" {
|
|
config.Cache.Disk.Size = "0"
|
|
}
|
|
if config.Cache.Disk.GCAlgorithm == "" {
|
|
config.Cache.Disk.GCAlgorithm = "lru"
|
|
}
|
|
|
|
return &config, nil
|
|
}
|
|
|
|
// SaveDefaultConfig creates a default configuration file
|
|
func SaveDefaultConfig(configPath string) error {
|
|
if configPath == "" {
|
|
configPath = "config.yaml"
|
|
}
|
|
|
|
defaultConfig := Config{
|
|
ListenAddress: ":80",
|
|
MaxConcurrentRequests: 50, // Reduced for home user (less concurrent load)
|
|
MaxRequestsPerClient: 3, // Reduced for home user (more conservative per client)
|
|
Cache: CacheConfig{
|
|
Memory: MemoryConfig{
|
|
Size: "1GB", // Recommended for systems that can spare 1GB RAM for caching
|
|
GCAlgorithm: "lru",
|
|
},
|
|
Disk: DiskConfig{
|
|
Size: "1TB", // Large HDD cache for home user
|
|
Path: "./disk",
|
|
GCAlgorithm: "lru", // Better for gaming patterns (keeps recently played games)
|
|
},
|
|
},
|
|
Upstream: "",
|
|
}
|
|
|
|
data, err := yaml.Marshal(&defaultConfig)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal default config: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile(configPath, data, 0644); err != nil {
|
|
return fmt.Errorf("failed to write default config file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|