Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions common_utils/notification_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package common_utils
import (
"context"
"encoding/json"
"fmt"
"strings"

sdcfg "github.com/sonic-net/sonic-gnmi/sonic_db_config"
Expand All @@ -28,16 +27,15 @@ func GetRedisDBClient() (*redis.Client, error) {
log.Errorf("DB err: %v", err)
return nil, err
}
rclient := redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "tcp",
Addr: addr,
Password: "", // no password set
DB: db,
DialTimeout: 0,
})
if rclient == nil {
return nil, fmt.Errorf("Cannot create redis client.")
}
sdcfg.ApplyRedisPoolSize(opts)
rclient := redis.NewClient(opts)
if _, err := rclient.Ping(context.Background()).Result(); err != nil {
return nil, err
}
Expand Down
12 changes: 8 additions & 4 deletions dialout/dialout_client/dialout_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,25 +658,29 @@ func DialOutRun(ctx context.Context, ccfg *ClientConfig) error {
if err != nil {
return err
}
redisDb = redis.NewClient(&redis.Options{
optsUnix := &redis.Options{
Network: "unix",
Addr: addr,
Password: "", // no password set
DB: dbn,
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(optsUnix)
redisDb = redis.NewClient(optsUnix)
} else {
addr, err := sdcfg.GetDbTcpAddr("CONFIG_DB", ns)
if err != nil {
return err
}
redisDb = redis.NewClient(&redis.Options{
optsTcp := &redis.Options{
Network: "tcp",
Addr: addr,
Password: "", // no password set
DB: dbn,
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(optsTcp)
redisDb = redis.NewClient(optsTcp)
}

separator, err := sdc.GetTableKeySeparator("CONFIG_DB", ns)
Expand Down
12 changes: 9 additions & 3 deletions gnmi_server/connection_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,21 @@ func (cm *ConnectionManager) PrepareRedis() {
log.Errorf("DB err: %v", err)
return
}
rclient = redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "tcp",
Addr: addr,
Password: "",
DB: db,
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(opts)
rclient = redis.NewClient(opts)

res, _ := rclient.HGetAll(context.Background(), "TELEMETRY_CONNECTIONS").Result()
res, err := rclient.HGetAll(context.Background(), table).Result()
if err != nil {
log.Errorf("Failed to read %s for cleanup: %v", table, err)
return
}

if res == nil {
return
Expand Down
7 changes: 5 additions & 2 deletions pkg/bypass/bypass.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/golang/glog"
gnmipb "github.com/openconfig/gnmi/proto/gnmi"
"github.com/redis/go-redis/v9"
sdcfg "github.com/sonic-net/sonic-gnmi/sonic_db_config"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import breaks the pure build because sonic_db_config also pulls in swsscommon. Could we move the existing implementation and test to a pure package like:

// internal/redisopts/redis_pool.go
package redisopts

const PoolSizeEnvVar = "GNMI_REDIS_POOL_SIZE"

func ApplyPoolSize(opts *redis.Options) {
    // Existing parsing and validation logic.
}

Then add internal/redisopts to PURE_PACKAGES in pure.mk and update the call sites to:

import "github.com/sonic-net/sonic-gnmi/internal/redisopts"

redisopts.ApplyPoolSize(opts)

"google.golang.org/grpc/metadata"
)

Expand Down Expand Up @@ -72,13 +73,15 @@ func getConfigDbClientDefault() (*redis.Client, error) {
}
}

client := redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: network,
Addr: addr,
Password: "",
DB: configDbId,
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(opts)
client := redis.NewClient(opts)
return client, nil
}

Expand Down
7 changes: 5 additions & 2 deletions pkg/interceptors/dpuproxy/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/redis/go-redis/v9"
sdcfg "github.com/sonic-net/sonic-gnmi/sonic_db_config"
)

// RedisClient defines the interface for Redis operations needed by DPU resolver.
Expand Down Expand Up @@ -31,10 +32,12 @@ func (a *GoRedisAdapter) HGetAll(ctx context.Context, key string) (map[string]st
// NewRedisClient creates a new Redis client connected to SONiC's Redis instance.
// It connects via Unix socket to the specified database.
func NewRedisClient(socketPath string, db int) *redis.Client {
return redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "unix",
Addr: socketPath,
Password: "", // SONiC Redis has no password
DB: db,
})
}
sdcfg.ApplyRedisPoolSize(opts)
return redis.NewClient(opts)
}
12 changes: 8 additions & 4 deletions sonic_data_client/db_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,13 +554,15 @@ func useRedisTcpClient() error {
continue
}
// DB connector for direct redis operation
redisDb := redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "tcp",
Addr: addr,
Password: "", // no password set
DB: int(dbn),
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(opts)
redisDb := redis.NewClient(opts)
Target2RedisDb[dbNamespace][dbName] = redisDb
}
}
Expand Down Expand Up @@ -589,13 +591,15 @@ func initRedisDbClients() {
continue
}
// DB connector for direct redis operation
redisDb := redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "unix",
Addr: addr,
Password: "", // no password set
DB: int(dbn),
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(opts)
redisDb := redis.NewClient(opts)
Target2RedisDb[dbNamespace][dbName] = redisDb
}
}
Expand Down
6 changes: 4 additions & 2 deletions sonic_data_client/events_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,15 @@ func update_stats(evtc *EventClient) {
return
}

rclient = redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "tcp",
Addr: addr,
Password: "", // no password set,
DB: dbId,
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(opts)
rclient = redis.NewClient(opts)

// Init current values for cumulative keys and clear for absolute
for _, key := range STATS_CUMULATIVE_KEYS {
Expand Down
6 changes: 4 additions & 2 deletions sonic_data_client/mixed_db_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,13 +635,15 @@ func initRedisDbMap() {
return
}
// DB connector for direct redis operation
redisDb := redis.NewClient(&redis.Options{
opts := &redis.Options{
Network: "unix",
Addr: addr,
Password: "", // no password set
DB: int(dbn),
DialTimeout: 0,
})
}
sdcfg.ApplyRedisPoolSize(opts)
redisDb := redis.NewClient(opts)
RedisDbMap[ns+":"+container+":"+dbName] = redisDb
}
}
Expand Down
48 changes: 48 additions & 0 deletions sonic_db_config/redis_pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// redis_pool.go provides optional, environment-driven tuning of the redis
// client connection pool used by gNMI's redis clients.

package dbconfig

import (
"os"
"strconv"

log "github.com/golang/glog"
"github.com/redis/go-redis/v9"
)

// RedisPoolSizeEnvVar is the environment variable used to override the redis
// client connection pool size. When it is not set, callers must leave the
// go-redis default pool size unchanged.
const RedisPoolSizeEnvVar = "GNMI_REDIS_POOL_SIZE"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a sonic-buildimage PR associated with this change?


// ApplyRedisPoolSize sets opts.PoolSize from the GNMI_REDIS_POOL_SIZE
// environment variable.
//
// If the variable is unset, empty, or not a positive integer, opts is left
// unchanged so go-redis keeps its default pool size (10 * runtime.GOMAXPROCS),
// which scales with the number of logical CPUs. Setting the variable lets
// operators cap per-client connections (and their buffers) on high-CPU
// systems to reduce memory consumption.
func ApplyRedisPoolSize(opts *redis.Options) {
Comment on lines +19 to +27
if opts == nil {
return
}
v, ok := os.LookupEnv(RedisPoolSizeEnvVar)
if !ok || v == "" {
// Not set: do not modify the default pool size.
return
}
n, err := strconv.Atoi(v)
if err != nil {
log.Warningf("Ignoring invalid %s=%q (must be a positive integer): %v",
RedisPoolSizeEnvVar, v, err)
return
}
if n <= 0 {
log.Warningf("Ignoring non-positive %s=%q (must be a positive integer)",
RedisPoolSizeEnvVar, v)
return
}
opts.PoolSize = n
}
45 changes: 45 additions & 0 deletions sonic_db_config/redis_pool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dbconfig

import (
"os"
"testing"

"github.com/redis/go-redis/v9"
)

func TestApplyRedisPoolSize(t *testing.T) {
tests := []struct {
name string
set bool
value string
expected int // expected PoolSize after apply; 0 means left at default
}{
{name: "unset leaves default", set: false, expected: 0},
{name: "empty leaves default", set: true, value: "", expected: 0},
{name: "valid positive value applied", set: true, value: "5", expected: 5},
{name: "zero leaves default", set: true, value: "0", expected: 0},
{name: "negative leaves default", set: true, value: "-3", expected: 0},
{name: "non-integer leaves default", set: true, value: "abc", expected: 0},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.set {
t.Setenv(RedisPoolSizeEnvVar, tt.value)
} else {
os.Unsetenv(RedisPoolSizeEnvVar)
}

opts := &redis.Options{}
ApplyRedisPoolSize(opts)
if opts.PoolSize != tt.expected {
t.Errorf("PoolSize = %d, want %d", opts.PoolSize, tt.expected)
}
})
}
}

func TestApplyRedisPoolSizeNilOptions(t *testing.T) {
// Must not panic on nil options.
ApplyRedisPoolSize(nil)
}
Loading