mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-14 04:07:46 +00:00
R80: req secret for introspection, pool conn on panic
This commit is contained in:
Vendored
+8
-3
@@ -376,9 +376,14 @@ func (r *RedisBackend) executeWithRetry(ctx context.Context, operation func(*Red
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the operation
|
||||
err = operation(conn)
|
||||
r.pool.Put(conn)
|
||||
// Execute the operation, guaranteeing the borrowed connection is
|
||||
// returned to the pool even if the operation panics (previously a
|
||||
// panic here leaked the connection and desynced the pool counters;
|
||||
// other pool call sites use defer for this).
|
||||
func() {
|
||||
defer func() { r.pool.Put(conn) }()
|
||||
err = operation(conn)
|
||||
}()
|
||||
|
||||
// Check context after operation - if canceled, don't bother retrying
|
||||
if ctx.Err() != nil {
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package backends
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestExecuteWithRetry_ReturnsConnOnPanic is a regression: executeWithRetry
|
||||
// returned the borrowed connection imperatively with no defer, so an operation
|
||||
// panic leaked the Redis connection out of the pool and desynced its counters.
|
||||
// The fix guarantees the connection is returned on all exit paths including
|
||||
// panic.
|
||||
func TestExecuteWithRetry_ReturnsConnOnPanic(t *testing.T) {
|
||||
pool, err := NewConnectionPool(&PoolConfig{MaxConnections: 1, ConnectTimeout: 50 * time.Millisecond})
|
||||
if err != nil {
|
||||
t.Fatalf("NewConnectionPool: %v", err)
|
||||
}
|
||||
|
||||
// Seed one available connection so executeWithRetry's Get succeeds without
|
||||
// dialing (no Redis server needed).
|
||||
pc, sw := net.Pipe()
|
||||
defer sw.Close()
|
||||
rc := &RedisConn{conn: pc, readTimeout: time.Second, writeTimeout: time.Second}
|
||||
pool.Put(rc)
|
||||
|
||||
if got := len(pool.connections); got != 1 {
|
||||
t.Fatalf("setup: expected one seeded connection, got %d", got)
|
||||
}
|
||||
|
||||
r := &RedisBackend{pool: pool}
|
||||
|
||||
func() {
|
||||
defer func() {
|
||||
if v := recover(); v == nil {
|
||||
t.Fatalf("expected operation to panic")
|
||||
}
|
||||
}()
|
||||
_ = r.executeWithRetry(context.Background(), func(c *RedisConn) error {
|
||||
panic("boom")
|
||||
})
|
||||
}()
|
||||
|
||||
if got := len(pool.connections); got != 1 {
|
||||
t.Fatalf("expected connection returned to pool after operation panic, got %d", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user