// Dial dials the local Redis server and selects database 9. To prevent // stomping on real data, DialTestDB fails if database 9 contains data. The // returned connection flushes database 9 on close. func Dial() (redis.Conn, error) { c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second) if err != nil { return nil, err } _, err = c.Do("SELECT", "9") if err != nil { c.Close() return nil, err } n, err := redis.Int(c.Do("DBSIZE")) if err != nil { c.Close() return nil, err } if n != 0 { c.Close() return nil, errors.New("database #9 is not empty, test can not continue") } return testConn{c}, nil }
func (app *App) configureRedis(configuration *configuration.Configuration) { if configuration.Redis.Addr == "" { ctxu.GetLogger(app).Infof("redis not configured") return } pool := &redis.Pool{ Dial: func() (redis.Conn, error) { // TODO(stevvooe): Yet another use case for contextual timing. ctx := context.WithValue(app, "redis.connect.startedat", time.Now()) done := func(err error) { logger := ctxu.GetLoggerWithField(ctx, "redis.connect.duration", ctxu.Since(ctx, "redis.connect.startedat")) if err != nil { logger.Errorf("redis: error connecting: %v", err) } else { logger.Infof("redis: connect %v", configuration.Redis.Addr) } } conn, err := redis.DialTimeout("tcp", configuration.Redis.Addr, configuration.Redis.DialTimeout, configuration.Redis.ReadTimeout, configuration.Redis.WriteTimeout) if err != nil { ctxu.GetLogger(app).Errorf("error connecting to redis instance %s: %v", configuration.Redis.Addr, err) done(err) return nil, err } // authorize the connection if configuration.Redis.Password != "" { if _, err = conn.Do("AUTH", configuration.Redis.Password); err != nil { defer conn.Close() done(err) return nil, err } } // select the database to use if configuration.Redis.DB != 0 { if _, err = conn.Do("SELECT", configuration.Redis.DB); err != nil { defer conn.Close() done(err) return nil, err } } done(nil) return conn, nil }, MaxIdle: configuration.Redis.Pool.MaxIdle, MaxActive: configuration.Redis.Pool.MaxActive, IdleTimeout: configuration.Redis.Pool.IdleTimeout, TestOnBorrow: func(c redis.Conn, t time.Time) error { // TODO(stevvooe): We can probably do something more interesting // here with the health package. _, err := c.Do("PING") return err }, Wait: false, // if a connection is not avialable, proceed without cache. } app.redis = pool // setup expvar registry := expvar.Get("registry") if registry == nil { registry = expvar.NewMap("registry") } registry.(*expvar.Map).Set("redis", expvar.Func(func() interface{} { return map[string]interface{}{ "Config": configuration.Redis, "Active": app.redis.ActiveCount(), } })) }