Golang: choosing a database on RedisPool in Redigo
using redigo, I create a pool, something like this:
&redis.Pool{
MaxIdle: 80,
MaxActive: 12000, // max number of connections
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", host+":"+port)
if err != nil {
panic(err.Error())
}
return c, err
}
the problem is that for every time i get a new connection i need to install the db as i am using different redis db since i host multiple sites in VPS.
So, something like this:
conn := pool.Get()
defer conn.Close()
conn.Do("SELECT", dbNumber) //this is the call I want to avoid
When choosing a db every time I work with redis it seems overkill and also creates a problem since I am using it for sessions i.e. with code not working with my redis connection from my pool it makes it impossible to set the correct one db for it.
What I would like to do is set the dbno for the pool so that whenever someone requests a new connection from the pool, it comes with the correct db already installed ie without setting it explicitly every time.
How did you solve this in your applications?
Thank.
source to share
If those libraries don't support it, you have two options:
-
post a patch to automate this (python lib does this, but be careful when saving state).
-
Wrap your redis pool with your own pool that automates this, something like (untested code, but you get the idea):
// a pool embedding the original pool and adding adbno state type DbnoPool struct { redis.Pool dbno int } // "overriding" the Get method func (p *DbnoPool)Get() Connection { conn := p.Pool.Get() conn.Do("SELECT", p.dbno) return conn } pool := &DbnoPool { redis.Pool{ MaxIdle: 80, MaxActive: 12000, // max number of connections Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", host+":"+port) if err != nil { panic(err.Error()) } return c, err }, 3, // the db number } //now you call it normally conn := pool.Get() defer conn.Close()
source to share
Select the database in your dialing function:
&redis.Pool{
MaxIdle: 80,
MaxActive: 12000, // max number of connections
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", host+":"+port)
if err != nil {
return nil, err
}
_, err := c.Do("SELECT", dbNum)
if err != nil {
c.Close()
return nil, err
}
return c, nil
}
Also, return a set error instead of panic.
source to share
The best way is to use DialOption
like DialDatabase
:
redisPool = &redis.Pool{
MaxIdle: AppConfig.DefaultInt("RedisMaxPool", 10),
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial(
"tcp",
AppConfig.DefaultString("RedisPath", ":6379"),
redis.DialDatabase(AppConfig.DefaultInt("RedisDB", 1)),
)
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
source to share