From 2cd217f110f736ec34f68b55e784b789b9939080 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Tue, 20 Aug 2019 12:29:54 +0300 Subject: [PATCH] add clusters support for sessiondb:redis:Radix() #1339 Former-commit-id: d748d1e19a29851abbbfc0264fd04c462158b645 --- sessions/sessiondb/redis/database.go | 8 ++- sessions/sessiondb/redis/driver_radix.go | 64 +++++++++++++++--------- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/sessions/sessiondb/redis/database.go b/sessions/sessiondb/redis/database.go index 847dcbb5..7345cc05 100644 --- a/sessions/sessiondb/redis/database.go +++ b/sessions/sessiondb/redis/database.go @@ -24,8 +24,14 @@ const ( type Config struct { // Network protocol. Defaults to "tcp". Network string - // Addr of the redis server. Defaults to "127.0.0.1:6379". + // Addr of a single redis server instance. + // See "Clusters" field for clusters support. + // Defaults to "127.0.0.1:6379". Addr string + // Clusters a list of network addresses for clusters. + // If not empty "Addr" is ignored. + // Currently only Radix() Driver supports it. + Clusters []string // Password string .If no password then no 'AUTH'. Defaults to "". Password string // If Database is empty "" then no 'SELECT'. Defaults to "". diff --git a/sessions/sessiondb/redis/driver_radix.go b/sessions/sessiondb/redis/driver_radix.go index dc69886f..cd07df7f 100644 --- a/sessions/sessiondb/redis/driver_radix.go +++ b/sessions/sessiondb/redis/driver_radix.go @@ -2,6 +2,7 @@ package redis import ( "fmt" + "math/rand" "strconv" "github.com/mediocregopher/radix/v3" @@ -39,32 +40,49 @@ func (r *RadixDriver) Connect(c Config) error { c.Delim = DefaultDelim } - customConnFunc := func(network, addr string) (radix.Conn, error) { - var options []radix.DialOpt + var options []radix.DialOpt - if c.Password != "" { - options = append(options, radix.DialAuthPass(c.Password)) - } - - if c.Timeout > 0 { - options = append(options, radix.DialTimeout(c.Timeout)) - } - - if c.Database != "" { // *dialOpts.selectDb is not exported on the 3rd-party library, - // but on its `DialSelectDB` option it does this: - // do.selectDB = strconv.Itoa(db) -> (string to int) - // so we can pass that string as int and it should work. - dbIndex, err := strconv.Atoi(c.Database) - if err == nil { - options = append(options, radix.DialSelectDB(dbIndex)) - } - - } - - return radix.Dial(network, addr, options...) + if c.Password != "" { + options = append(options, radix.DialAuthPass(c.Password)) } - pool, err := radix.NewPool(c.Network, c.Addr, c.MaxActive, radix.PoolConnFunc(customConnFunc)) + if c.Timeout > 0 { + options = append(options, radix.DialTimeout(c.Timeout)) + } + + if c.Database != "" { // *dialOpts.selectDb is not exported on the 3rd-party library, + // but on its `DialSelectDB` option it does this: + // do.selectDB = strconv.Itoa(db) -> (string to int) + // so we can pass that string as int and it should work. + dbIndex, err := strconv.Atoi(c.Database) + if err == nil { + options = append(options, radix.DialSelectDB(dbIndex)) + } + + } + + var connFunc radix.ConnFunc + + if len(c.Clusters) > 0 { + cluster, err := radix.NewCluster(c.Clusters) + if err != nil { + // maybe an + // ERR This instance has cluster support disabled + return err + } + + connFunc = func(network, addr string) (radix.Conn, error) { + topo := cluster.Topo() + node := topo[rand.Intn(len(topo))] + return radix.Dial(c.Network, node.Addr, options...) + } + } else { + connFunc = func(network, addr string) (radix.Conn, error) { + return radix.Dial(c.Network, c.Addr, options...) + } + } + + pool, err := radix.NewPool(c.Network, c.Addr, c.MaxActive, radix.PoolConnFunc(connFunc)) if err != nil { return err }