mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-20 04:57:02 +00:00
fix(cache): harden cache backends, resilience, recovery, and transports
- RESP -ERR no longer closes healthy conn / aborts batch; global cap replacement-aware - global health-check pass serialized (latent data race); MemoryMonitor via ResourceManager - token-exchange retry, open-circuit rejections counted as failures - TLS-posture matching transport reuse (no silent InsecureSkipVerify handoff)
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
//go:build !yaegi
|
||||
|
||||
package backends
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestHybridBackend_CloseConcurrentSet_NoPanic regresses a send-on-closed-
|
||||
// channel panic in HybridBackend. Close() used to close asyncWriteBuffer
|
||||
// while a concurrent Set() may be mid-select on
|
||||
// `h.asyncWriteBuffer <- item`, which can panic ("send on closed
|
||||
// channel") and crash the process at shutdown. This exercises many
|
||||
// Close+Set cycles concurrently and asserts no panic escapes.
|
||||
func TestHybridBackend_CloseConcurrentSet_NoPanic(t *testing.T) {
|
||||
for i := 0; i < 50; i++ {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
primary := newMockBackend()
|
||||
secondary := newMockBackend()
|
||||
|
||||
h, err := NewHybridBackend(&HybridConfig{
|
||||
Primary: primary,
|
||||
Secondary: secondary,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("new hybrid: %v", err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var panicked sync.Map
|
||||
|
||||
// Writers hammer Set concurrently with Close using async (non-
|
||||
// critical) cache type so the send goes through asyncWriteBuffer.
|
||||
for w := 0; w < 8; w++ {
|
||||
wg.Add(1)
|
||||
go func(w int) {
|
||||
defer wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
panicked.Store(true, fmt.Sprintf("writer %d: %v", w, r))
|
||||
}
|
||||
}()
|
||||
for k := 0; k < 200; k++ {
|
||||
// "session:" prefix is not blacklist/token -> async path.
|
||||
_ = h.Set(ctx, fmt.Sprintf("session:user%d:%d", w, k), []byte("value"), time.Minute)
|
||||
}
|
||||
}(w)
|
||||
}
|
||||
|
||||
// Close concurrently with the writers.
|
||||
_ = h.Close()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if v, ok := panicked.Load(true); ok {
|
||||
t.Fatalf("panic during Close+concurrent Set: %v", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user