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.

+3


source to share


4 answers


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()
    
          

+2


source


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.

+3


source


You can use redis.DialOption

: redis.DialDatabase

,redis.DialPassword

conn, err := redis.Dial("tcp", "127.0.0.1:6379", redis.DialDatabase(1))
if err != nil {
    panic(err)
}
defer conn.Close()

      

+2


source


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
    },
}

      

0


source







All Articles