fix(server): resolve memory leaks causing OOM in k8s deployment

- usage/logger_plugin: cap modelStats.Details at 1000 entries per model
- cache/signature_cache: add background cleanup for expired sessions (10 min)
- management/handler: add background cleanup for stale IP rate-limit entries (1 hr)
- executor/cache_helpers: add mutex protection and TTL cleanup for codexCacheMap (15 min)
- executor/codex_executor: use thread-safe cache accessors

Add reproduction tests demonstrating leak behavior before/after fixes.

Amp-Thread-ID: https://ampcode.com/threads/T-019ba0fc-1d7b-7338-8e1d-ca0520412777
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
hemanta212
2026-01-09 13:33:46 +05:45
parent d47b7dc79a
commit 47dacce6ea
7 changed files with 526 additions and 6 deletions

View File

@@ -87,6 +87,10 @@ type modelStats struct {
Details []RequestDetail
}
// maxDetailsPerModel limits the number of request details retained per model
// to prevent unbounded memory growth. Oldest entries are dropped when exceeded.
const maxDetailsPerModel = 1000
// RequestDetail stores the timestamp and token usage for a single request.
type RequestDetail struct {
Timestamp time.Time `json:"timestamp"`
@@ -221,6 +225,11 @@ func (s *RequestStatistics) updateAPIStats(stats *apiStats, model string, detail
modelStatsValue.TotalRequests++
modelStatsValue.TotalTokens += detail.Tokens.TotalTokens
modelStatsValue.Details = append(modelStatsValue.Details, detail)
// Prevent unbounded growth by dropping oldest entries when limit exceeded
if len(modelStatsValue.Details) > maxDetailsPerModel {
excess := len(modelStatsValue.Details) - maxDetailsPerModel
modelStatsValue.Details = modelStatsValue.Details[excess:]
}
}
// Snapshot returns a copy of the aggregated metrics for external consumption.