fix: restore tracing endpoint validation; honor per-side client timeouts; cache eviction target; redis close

- tracing: validateEndpoint used fmt.Sscanf("%s:%d") which treats %s as
  greedy, so every valid host:port endpoint failed and traced==nil disabled
  tracing entirely. Validate with net.SplitHostPort (pure helper, port range
  0-65535); test TestValidateEndpoint.
- proxy: createFasthttpClient used clientTimeout for every timeout slot,
  ignoring the parsed CLIENT_READ_TIMEOUT/CLIENT_WRITE_TIMEOUT (silent
  config loss, documented separately in README). Honour per-side read/write
  timeouts, falling back to client timeout when unset.
- cache/memory: evictToFreeMemory capped candidates at maxCacheSize/5 and
  stopped at the subset end, so a large write could leave the cache over
  its memory limit. Collect all entries and sort.Slice (correct + O(n log n)
  vs O(cap^2)), evict until the target is met or the cache is drained.
- cache/redis: the Redis cache client was never closed at shutdown (unlike
  the metrics aggregator). Add RedisConfig.Close, CacheWrapper.Close, a
  cache.Shutdown and register it with the ShutdownManager.
This commit is contained in:
2026-08-13 07:16:52 +01:00
parent fc28c65681
commit 14be2398e8
10 changed files with 167 additions and 37 deletions
+12 -4
View File
@@ -229,10 +229,18 @@ func createFasthttpClient(clientConfig *config) *fasthttp.Client {
clientTimeout = 30 * time.Second // Default timeout of 30 seconds
}
// For timeout behavior, use the client timeout for all timeout settings
// to ensure consistent behavior
readTimeout := clientTimeout
writeTimeout := clientTimeout
// Honour the per-side read/write timeouts (CLIENT_READ_TIMEOUT /
// CLIENT_WRITE_TIMEOUT); they fall back to the client timeout when not
// explicitly configured, so behaviour is unchanged for operators who only
// set CLIENT_TIMEOUT.
readTimeout := time.Duration(clientConfig.Client.ReadTimeout) * time.Second
if readTimeout <= 0 {
readTimeout = clientTimeout
}
writeTimeout := time.Duration(clientConfig.Client.WriteTimeout) * time.Second
if writeTimeout <= 0 {
writeTimeout = clientTimeout
}
// Create a custom dialer with timeout
dialer := &fasthttp.TCPDialer{