Commit 81ae4251 authored by Steven's avatar Steven

chore: fix linter

parent eca91d5c
...@@ -12,19 +12,19 @@ import ( ...@@ -12,19 +12,19 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
// Profiler provides HTTP endpoints for memory profiling // Profiler provides HTTP endpoints for memory profiling.
type Profiler struct { type Profiler struct {
memStatsLogInterval time.Duration memStatsLogInterval time.Duration
} }
// NewProfiler creates a new profiler // NewProfiler creates a new profiler.
func NewProfiler() *Profiler { func NewProfiler() *Profiler {
return &Profiler{ return &Profiler{
memStatsLogInterval: 1 * time.Minute, memStatsLogInterval: 1 * time.Minute,
} }
} }
// RegisterRoutes adds profiling endpoints to the Echo server // RegisterRoutes adds profiling endpoints to the Echo server.
func (p *Profiler) RegisterRoutes(e *echo.Echo) { func (p *Profiler) RegisterRoutes(e *echo.Echo) {
// Register pprof handlers // Register pprof handlers
g := e.Group("/debug/pprof") g := e.Group("/debug/pprof")
...@@ -41,7 +41,7 @@ func (p *Profiler) RegisterRoutes(e *echo.Echo) { ...@@ -41,7 +41,7 @@ func (p *Profiler) RegisterRoutes(e *echo.Echo) {
g.GET("/mutex", echo.WrapHandler(http.HandlerFunc(pprof.Handler("mutex").ServeHTTP))) g.GET("/mutex", echo.WrapHandler(http.HandlerFunc(pprof.Handler("mutex").ServeHTTP)))
g.GET("/threadcreate", echo.WrapHandler(http.HandlerFunc(pprof.Handler("threadcreate").ServeHTTP))) g.GET("/threadcreate", echo.WrapHandler(http.HandlerFunc(pprof.Handler("threadcreate").ServeHTTP)))
// Add a custom memory stats endpoint // Add a custom memory stats endpoint.
g.GET("/memstats", func(c echo.Context) error { g.GET("/memstats", func(c echo.Context) error {
var m runtime.MemStats var m runtime.MemStats
runtime.ReadMemStats(&m) runtime.ReadMemStats(&m)
...@@ -58,13 +58,13 @@ func (p *Profiler) RegisterRoutes(e *echo.Echo) { ...@@ -58,13 +58,13 @@ func (p *Profiler) RegisterRoutes(e *echo.Echo) {
}) })
} }
// StartMemoryMonitor starts a goroutine that periodically logs memory stats // StartMemoryMonitor starts a goroutine that periodically logs memory stats.
func (p *Profiler) StartMemoryMonitor(ctx context.Context) { func (p *Profiler) StartMemoryMonitor(ctx context.Context) {
go func() { go func() {
ticker := time.NewTicker(p.memStatsLogInterval) ticker := time.NewTicker(p.memStatsLogInterval)
defer ticker.Stop() defer ticker.Stop()
// Store previous heap allocation to track growth // Store previous heap allocation to track growth.
var lastHeapAlloc uint64 var lastHeapAlloc uint64
var lastNumGC uint32 var lastNumGC uint32
...@@ -74,7 +74,7 @@ func (p *Profiler) StartMemoryMonitor(ctx context.Context) { ...@@ -74,7 +74,7 @@ func (p *Profiler) StartMemoryMonitor(ctx context.Context) {
var m runtime.MemStats var m runtime.MemStats
runtime.ReadMemStats(&m) runtime.ReadMemStats(&m)
// Calculate heap growth since last check // Calculate heap growth since last check.
heapGrowth := int64(m.HeapAlloc) - int64(lastHeapAlloc) heapGrowth := int64(m.HeapAlloc) - int64(lastHeapAlloc)
gcCount := m.NumGC - lastNumGC gcCount := m.NumGC - lastNumGC
...@@ -90,11 +90,11 @@ func (p *Profiler) StartMemoryMonitor(ctx context.Context) { ...@@ -90,11 +90,11 @@ func (p *Profiler) StartMemoryMonitor(ctx context.Context) {
"gcPause", time.Duration(m.PauseNs[(m.NumGC+255)%256]).String(), "gcPause", time.Duration(m.PauseNs[(m.NumGC+255)%256]).String(),
) )
// Track values for next iteration // Track values for next iteration.
lastHeapAlloc = m.HeapAlloc lastHeapAlloc = m.HeapAlloc
lastNumGC = m.NumGC lastNumGC = m.NumGC
// Force GC if memory usage is high to see if objects can be reclaimed // Force GC if memory usage is high to see if objects can be reclaimed.
if m.HeapAlloc > 500*1024*1024 { // 500 MB threshold if m.HeapAlloc > 500*1024*1024 { // 500 MB threshold
slog.Info("forcing garbage collection due to high memory usage") slog.Info("forcing garbage collection due to high memory usage")
runtime.GC() runtime.GC()
...@@ -106,7 +106,7 @@ func (p *Profiler) StartMemoryMonitor(ctx context.Context) { ...@@ -106,7 +106,7 @@ func (p *Profiler) StartMemoryMonitor(ctx context.Context) {
}() }()
} }
// byteCountIEC converts bytes to a human-readable string (MiB, GiB) // byteCountIEC converts bytes to a human-readable string (MiB, GiB).
func byteCountIEC(b uint64) string { func byteCountIEC(b uint64) string {
const unit = 1024 const unit = 1024
if b < unit { if b < unit {
......
...@@ -7,53 +7,53 @@ import ( ...@@ -7,53 +7,53 @@ import (
"time" "time"
) )
// Interface defines the operations a cache must support // Interface defines the operations a cache must support.
type Interface interface { type Interface interface {
// Set adds a value to the cache with the default TTL // Set adds a value to the cache with the default TTL.
Set(ctx context.Context, key string, value interface{}) Set(ctx context.Context, key string, value any)
// SetWithTTL adds a value to the cache with a custom TTL // SetWithTTL adds a value to the cache with a custom TTL.
SetWithTTL(ctx context.Context, key string, value interface{}, ttl time.Duration) SetWithTTL(ctx context.Context, key string, value any, ttl time.Duration)
// Get retrieves a value from the cache // Get retrieves a value from the cache.
Get(ctx context.Context, key string) (interface{}, bool) Get(ctx context.Context, key string) (any, bool)
// Delete removes a value from the cache // Delete removes a value from the cache.
Delete(ctx context.Context, key string) Delete(ctx context.Context, key string)
// Clear removes all values from the cache // Clear removes all values from the cache.
Clear(ctx context.Context) Clear(ctx context.Context)
// Size returns the number of items in the cache // Size returns the number of items in the cache.
Size() int64 Size() int64
// Close stops all background tasks and releases resources // Close stops all background tasks and releases resources.
Close() error Close() error
} }
// item represents a cached value with metadata // item represents a cached value with metadata.
type item struct { type item struct {
value interface{} value any
expiration time.Time expiration time.Time
size int // Approximate size in bytes size int // Approximate size in bytes
} }
// Config contains options for configuring a cache // Config contains options for configuring a cache.
type Config struct { type Config struct {
// DefaultTTL is the default time-to-live for cache entries // DefaultTTL is the default time-to-live for cache entries.
DefaultTTL time.Duration DefaultTTL time.Duration
// CleanupInterval is how often the cache runs cleanup // CleanupInterval is how often the cache runs cleanup.
CleanupInterval time.Duration CleanupInterval time.Duration
// MaxItems is the maximum number of items allowed in the cache // MaxItems is the maximum number of items allowed in the cache.
MaxItems int MaxItems int
// OnEviction is called when an item is evicted from the cache // OnEviction is called when an item is evicted from the cache.
OnEviction func(key string, value interface{}) OnEviction func(key string, value any)
} }
// DefaultConfig returns a default configuration for the cache // DefaultConfig returns a default configuration for the cache.
func DefaultConfig() Config { func DefaultConfig() Config {
return Config{ return Config{
DefaultTTL: 10 * time.Minute, DefaultTTL: 10 * time.Minute,
...@@ -63,7 +63,7 @@ func DefaultConfig() Config { ...@@ -63,7 +63,7 @@ func DefaultConfig() Config {
} }
} }
// Cache is a thread-safe in-memory cache with TTL and memory management // Cache is a thread-safe in-memory cache with TTL and memory management.
type Cache struct { type Cache struct {
data sync.Map data sync.Map
config Config config Config
...@@ -72,7 +72,7 @@ type Cache struct { ...@@ -72,7 +72,7 @@ type Cache struct {
closedChan chan struct{} closedChan chan struct{}
} }
// New creates a new memory cache with the given configuration // New creates a new memory cache with the given configuration.
func New(config Config) *Cache { func New(config Config) *Cache {
c := &Cache{ c := &Cache{
config: config, config: config,
...@@ -84,27 +84,26 @@ func New(config Config) *Cache { ...@@ -84,27 +84,26 @@ func New(config Config) *Cache {
return c return c
} }
// NewDefault creates a new memory cache with default configuration // NewDefault creates a new memory cache with default configuration.
func NewDefault() *Cache { func NewDefault() *Cache {
return New(DefaultConfig()) return New(DefaultConfig())
} }
// Set adds a value to the cache with the default TTL // Set adds a value to the cache with the default TTL.
func (c *Cache) Set(ctx context.Context, key string, value interface{}) { func (c *Cache) Set(ctx context.Context, key string, value any) {
c.SetWithTTL(ctx, key, value, c.config.DefaultTTL) c.SetWithTTL(ctx, key, value, c.config.DefaultTTL)
} }
// SetWithTTL adds a value to the cache with a custom TTL // SetWithTTL adds a value to the cache with a custom TTL.
func (c *Cache) SetWithTTL(ctx context.Context, key string, value interface{}, ttl time.Duration) { func (c *Cache) SetWithTTL(ctx context.Context, key string, value any, ttl time.Duration) {
// Estimate size of the item (very rough approximation) // Estimate size of the item (very rough approximation).
size := estimateSize(value) size := estimateSize(value)
// Check if item already exists to avoid double counting // Check if item already exists to avoid double counting.
if _, exists := c.data.Load(key); exists { if _, exists := c.data.Load(key); exists {
c.data.Delete(key) c.data.Delete(key)
// Don't decrement count - we'll replace it
} else { } else {
// Only increment if this is a new key // Only increment if this is a new key.
atomic.AddInt64(&c.itemCount, 1) atomic.AddInt64(&c.itemCount, 1)
} }
...@@ -114,14 +113,14 @@ func (c *Cache) SetWithTTL(ctx context.Context, key string, value interface{}, t ...@@ -114,14 +113,14 @@ func (c *Cache) SetWithTTL(ctx context.Context, key string, value interface{}, t
size: size, size: size,
}) })
// If we're over the max items, clean up old items // If we're over the max items, clean up old items.
if c.config.MaxItems > 0 && atomic.LoadInt64(&c.itemCount) > int64(c.config.MaxItems) { if c.config.MaxItems > 0 && atomic.LoadInt64(&c.itemCount) > int64(c.config.MaxItems) {
c.cleanupOldest() c.cleanupOldest()
} }
} }
// Get retrieves a value from the cache // Get retrieves a value from the cache.
func (c *Cache) Get(ctx context.Context, key string) (interface{}, bool) { func (c *Cache) Get(ctx context.Context, key string) (any, bool) {
value, ok := c.data.Load(key) value, ok := c.data.Load(key)
if !ok { if !ok {
return nil, false return nil, false
...@@ -142,7 +141,7 @@ func (c *Cache) Get(ctx context.Context, key string) (interface{}, bool) { ...@@ -142,7 +141,7 @@ func (c *Cache) Get(ctx context.Context, key string) (interface{}, bool) {
return itm.value, true return itm.value, true
} }
// Delete removes a value from the cache // Delete removes a value from the cache.
func (c *Cache) Delete(ctx context.Context, key string) { func (c *Cache) Delete(ctx context.Context, key string) {
if value, loaded := c.data.LoadAndDelete(key); loaded { if value, loaded := c.data.LoadAndDelete(key); loaded {
atomic.AddInt64(&c.itemCount, -1) atomic.AddInt64(&c.itemCount, -1)
...@@ -154,10 +153,10 @@ func (c *Cache) Delete(ctx context.Context, key string) { ...@@ -154,10 +153,10 @@ func (c *Cache) Delete(ctx context.Context, key string) {
} }
} }
// Clear removes all values from the cache // Clear removes all values from the cache.
func (c *Cache) Clear(ctx context.Context) { func (c *Cache) Clear(ctx context.Context) {
if c.config.OnEviction != nil { if c.config.OnEviction != nil {
c.data.Range(func(key, value interface{}) bool { c.data.Range(func(key, value any) bool {
itm := value.(item) itm := value.(item)
c.config.OnEviction(key.(string), itm.value) c.config.OnEviction(key.(string), itm.value)
return true return true
...@@ -168,12 +167,12 @@ func (c *Cache) Clear(ctx context.Context) { ...@@ -168,12 +167,12 @@ func (c *Cache) Clear(ctx context.Context) {
atomic.StoreInt64(&c.itemCount, 0) atomic.StoreInt64(&c.itemCount, 0)
} }
// Size returns the number of items in the cache // Size returns the number of items in the cache.
func (c *Cache) Size() int64 { func (c *Cache) Size() int64 {
return atomic.LoadInt64(&c.itemCount) return atomic.LoadInt64(&c.itemCount)
} }
// Close stops the cache cleanup goroutine // Close stops the cache cleanup goroutine.
func (c *Cache) Close() error { func (c *Cache) Close() error {
select { select {
case <-c.stopChan: case <-c.stopChan:
...@@ -186,7 +185,7 @@ func (c *Cache) Close() error { ...@@ -186,7 +185,7 @@ func (c *Cache) Close() error {
} }
} }
// cleanupLoop periodically cleans up expired items // cleanupLoop periodically cleans up expired items.
func (c *Cache) cleanupLoop() { func (c *Cache) cleanupLoop() {
ticker := time.NewTicker(c.config.CleanupInterval) ticker := time.NewTicker(c.config.CleanupInterval)
defer func() { defer func() {
...@@ -204,12 +203,12 @@ func (c *Cache) cleanupLoop() { ...@@ -204,12 +203,12 @@ func (c *Cache) cleanupLoop() {
} }
} }
// cleanup removes expired items // cleanup removes expired items.
func (c *Cache) cleanup() { func (c *Cache) cleanup() {
evicted := make(map[string]interface{}) evicted := make(map[string]any)
count := 0 count := 0
c.data.Range(func(key, value interface{}) bool { c.data.Range(func(key, value any) bool {
itm := value.(item) itm := value.(item)
if time.Now().After(itm.expiration) { if time.Now().After(itm.expiration) {
c.data.Delete(key) c.data.Delete(key)
...@@ -234,7 +233,7 @@ func (c *Cache) cleanup() { ...@@ -234,7 +233,7 @@ func (c *Cache) cleanup() {
} }
} }
// cleanupOldest removes the oldest items if we're over the max items // cleanupOldest removes the oldest items if we're over the max items.
func (c *Cache) cleanupOldest() { func (c *Cache) cleanupOldest() {
threshold := c.config.MaxItems / 5 // Remove 20% of max items at once threshold := c.config.MaxItems / 5 // Remove 20% of max items at once
if threshold < 1 { if threshold < 1 {
...@@ -251,12 +250,12 @@ func (c *Cache) cleanupOldest() { ...@@ -251,12 +250,12 @@ func (c *Cache) cleanupOldest() {
// Find the oldest items // Find the oldest items
type keyExpPair struct { type keyExpPair struct {
key string key string
value interface{} value any
expiration time.Time expiration time.Time
} }
candidates := make([]keyExpPair, 0, threshold) candidates := make([]keyExpPair, 0, threshold)
c.data.Range(func(key, value interface{}) bool { c.data.Range(func(key, value any) bool {
itm := value.(item) itm := value.(item)
if len(candidates) < threshold { if len(candidates) < threshold {
candidates = append(candidates, keyExpPair{key.(string), itm.value, itm.expiration}) candidates = append(candidates, keyExpPair{key.(string), itm.value, itm.expiration})
...@@ -296,14 +295,14 @@ func (c *Cache) cleanupOldest() { ...@@ -296,14 +295,14 @@ func (c *Cache) cleanupOldest() {
} }
} }
// estimateSize attempts to estimate the memory footprint of a value // estimateSize attempts to estimate the memory footprint of a value.
func estimateSize(value interface{}) int { func estimateSize(value any) int {
switch v := value.(type) { switch v := value.(type) {
case string: case string:
return len(v) + 24 // base size + string overhead return len(v) + 24 // base size + string overhead
case []byte: case []byte:
return len(v) + 24 // base size + slice overhead return len(v) + 24 // base size + slice overhead
case map[string]interface{}: case map[string]any:
return len(v) * 64 // rough estimate return len(v) * 64 // rough estimate
default: default:
return 64 // default conservative estimate return 64 // default conservative estimate
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment