// adds a status to a user's follower's timelines func syndicateStatus(uid, sid, time string, c redis.Conn) (bool, error) { defer c.Close() // get all the followers user ids sorted by score // if this is exceptionally large we may want to do the syndication in stages r, err := redis.Values(c.Do("ZRANGEBYSCORE", "followers:"+uid, "-inf", "+inf")) if err != nil { return false, err } var followerSlice []string if err := redis.ScanSlice(r, &followerSlice); err != nil { return false, nil } // push the status in a single transaction c.Do("MULTI") for i := range followerSlice { c.Do("ZADD", "timeline:"+followerSlice[i], time, sid) } if _, err := c.Do("EXEC"); err != nil { return false, err } return true, nil }
func read(server string, exitChan chan struct{}) { var conn redis.Conn var err error defer func() { if conn != nil { conn.Close() } if err != nil { log.Print(err) } exitChan <- struct{}{} }() conn, err = redis.Dial("tcp", server) if err != nil { return } for { i := rand.Int() % maxKeyNum key := fmt.Sprintf("key:%d", i) if reply, err := conn.Do("GET", key); err != nil { log.Printf("get error %v %v", key, err) break } else { log.Printf("key->%s", reply) } } }
// creates a status hash structure and returns it's status id. func createStatus(message string, uid int, c redis.Conn) (int, error) { var login string var sid int defer c.Close() c.Do("MULTI") // get login name for user with id c.Do("HGET", "user:"******"login") // get the incremented global status count c.Do("INCR", "status:id") // reply contains both the login for the uid and the global status count reply, err := redis.Values(c.Do("EXEC")) if err != nil { return -1, err } // scan reply into the local variables if _, err := redis.Scan(reply, &login, &sid); err != nil { return -1, err } // set all the appropriate values in the hash store if _, err := c.Do("HMSET", "status:"+strconv.Itoa(sid), "message", message, "posted", time.Now().Unix(), "id", sid, "uid", uid, "login", login); err != nil { return -1, err } // increment the user's post count if _, err := c.Do("HINCRBY", "user:"******"posts", 1); err != nil { return -1, err } return sid, nil }
func NewRedisRegistryWithConfig(conf *RedisConfig) (registry Registry) { pool := &redis.Pool{ MaxIdle: conf.MaxIdle, IdleTimeout: time.Duration(conf.IdleTimeoutS) * time.Second, MaxActive: conf.MaxActive, Dial: func() (redis.Conn, error) { var c redis.Conn var err error c, err = redis.DialTimeout("tcp", conf.Address, time.Duration(conf.ConnectTimeoutMs)*time.Millisecond, time.Duration(conf.ReadTimeoutMs)*time.Millisecond, time.Duration(conf.WriteTimeoutMs)*time.Millisecond) if err != nil { return nil, err } //password authentication if len(conf.Password) > 0 { if _, err_pass := c.Do("AUTH", conf.Password); err_pass != nil { c.Close() } } return c, err }, } return &redisRegistry{pool} }
func makeConn(addr, pwd string) (conn *redisConn, err error) { log.Info("makeConn|%v|%v", addr, pwd) conn = nil const dataTimeout = 5 * time.Second const connTimeout = 2 * time.Second var c redis.Conn if c, err = redis.DialTimeout("tcp", addr, connTimeout, dataTimeout, dataTimeout); err != nil { log.Error("makeConn|DialTimeout|%v", err) return } if pwd != "" { if _, err = c.Do("AUTH", pwd); err != nil { log.Error("makeConn|auth|%v", err) c.Close() return } } if _, err = c.Do("get", "__test"); err != nil { log.Error("makeConn|get|%v", err) c.Close() return } log.Info("makeConn|ok|%v", addr) var now = time.Now().Unix() conn = &redisConn{c, addr, seed, now + pingInterval, now} seed++ return }
//创建一个新的redis连接 func NewRedisCache(ip string, port string, password string) (*RedisCache, error) { var ( c redis.Conn err error ) c, err = redis.DialTimeout("tcp", ip+":"+port, 0, 1*time.Second, 1*time.Second) if err != nil { glog.Error("Error:", err) return nil, err } if password != "" { _, err = c.Do("AUTH", password) if err != nil { c.Close() glog.Error("Error:", err) return nil, err } } return &RedisCache{ session: c, }, err }
func (r *RedisBackend) testOnBorrow(c redis.Conn, t time.Time) error { _, err := c.Do("PING") if err != nil { defer c.Close() } return err }
func findSession(w http.ResponseWriter, r *http.Request, rc redis.Conn) (*Session, error) { session := new(Session) usertokenCookie, err := r.Cookie("usertoken") if err != nil { return session, lwutil.NewErr(err) } usertoken := usertokenCookie.Value //redis if rc == nil { rc = redisPool.Get() defer rc.Close() } sessionBytes, err := redis.Bytes(rc.Do("get", fmt.Sprintf("sessions/%s", usertoken))) if err != nil { return session, lwutil.NewErr(err) } err = json.Unmarshal(sessionBytes, session) lwutil.CheckError(err, "") //update session dt := time.Now().Sub(session.Born) if dt > sessionUpdateSecond*time.Second { newSession(w, session.Userid, session.Username, session.Appid, rc) } return session, nil }
func UpdateRedis(readChan chan *Distribution, id int) error { var redisConn redis.Conn var now int lastStatusTime := int(time.Now().Unix()) updateCount := 0 for dist := range readChan { // Only do a update if we have all the data necissary or we expect // there to be a decay event now = int(time.Now().Unix()) if dist.Full() || float64(now-dist.LastSyncT)*dist.Rate > 0.75 { redisConn = redisServer.GetConnection() err := UpdateDistribution(redisConn, dist) if err != nil { log.Printf("[%d] Failed to update: %s: %v: %s", id, dist.Name, redisConn.Err(), err.Error()) } updateCount += 1 if now-lastStatusTime > *UpdateOutputTime { rate := float64(updateCount) / float64(now-lastStatusTime) log.Printf("[%d] Performing redis updates at %e updates/second", id, rate) lastStatusTime = now updateCount = 0 } redisConn.Close() } } return nil }
func RedisDo(commandName string, args ...interface{}) (interface{}, error) { var redisConn redis.Conn var err error for i := 0; i < redisRetryCount; i++ { if redisConn, err = redis.Dial("tcp", redisAddress); err != nil { fog.Warn("redis.Dial: %s", err) time.Sleep(5 * time.Second) continue } result, err := redisConn.Do(commandName, args...) redisConn.Close() if err != nil { fog.Warn("RedisDo: %s", err) time.Sleep(1 * time.Second) continue } return result, nil } return nil, fmt.Errorf("RedisDo: failed after %d retries %s", redisRetryCount, err) }
func (this *redisPool) testConn(conn redis.Conn) error { if _, err := conn.Do("PING"); err != nil { conn.Close() return err } return nil }
func (this *redisPool) Close(conn redis.Conn) { select { case this.connections <- conn: return default: conn.Close() } }
func auth(c redis.Conn, password string) error { if _, err := c.Do("AUTH", password); err != nil { c.Close() return err } return nil }
// FetchRedisStats returns a map of requested stats func FetchRedisInfo(stat string, c rd.Conn) (map[string]string, error) { defer c.Close() out, err := rd.String(c.Do("INFO", stat)) if err != nil { logp.Err("Error retrieving INFO stats: %v", err) return nil, err } return ParseRedisInfo(out), nil }
func PutInRedisPool(conn redis.Conn) { if RedisPool == nil { RedisPool = make(chan redis.Conn, MAX_POOL_SIZE) } if len(RedisPool) >= MAX_POOL_SIZE { conn.Close() return } RedisPool <- conn }
func putRedis(conn redis.Conn) { if redisPool == nil { redisPool = make(chan redis.Conn, MAX_POOL_SIZE) } if len(redisPool) >= MAX_POOL_SIZE { conn.Close() return } redisPool <- conn }
func putRedis(conn redis.Conn) { // 基于函数和接口间互不信任原则,这里再判断一次,养成这个好习惯哦成这个好习惯哦 if redisPoll == nil { redisPoll = make(chan redis.Conn, MAX_POOL_SIZE) } if len(redisPoll) >= MAX_POOL_SIZE { conn.Close() return } redisPoll <- conn }
func main() { var id int var use_redis *bool = flag.Bool("r", false, "use redis cache") flag.Parse() // Redis Connection Part var err error var c redis.Conn if *use_redis { c, err = redis.Dial("tcp", "127.0.0.1:6379") if err != nil { panic(err) } defer c.Close() } // MySQL Connection Part db, err := sql.Open("mysql", "root@tcp(127.0.0.1:3306)/mysql") if err != nil { panic(err.Error()) // Just for example purpose. You should use proper error handling instead of panic } defer db.Close() for id = 0; id < 500; id++ { var command string if *use_redis { command, err = redis.String(c.Do("GET", id)) } if err != nil || !*use_redis { // Open doesn't open a connection. Validate DSN data: err = db.Ping() if err != nil { panic(err.Error()) // proper error handling instead of panic in your app } err = db.QueryRow("SELECT name FROM help_topic WHERE help_topic_id = ?", id).Scan(&command) switch { case err == sql.ErrNoRows: panic("No command with that ID.") case err != nil: panic(err) default: //fmt.Println("Found in MySQL") if *use_redis { c.Do("SET", id, command) } } } //fmt.Printf("Command is %s\n", command) } }
func UpdateRedis(readChan chan *Distribution, id int) error { var redisConn redis.Conn for dist := range readChan { log.Printf("[%d] Updating distribution: %s", id, dist.Name) redisConn = redisServer.GetConnection() err := UpdateDistribution(redisConn, dist) if err != nil { log.Printf("[%d] Failed to update: %s: %v: %s", id, dist.Name, redisConn.Err(), err.Error()) } redisConn.Close() } return nil }
func (d *Disque) explore() (err error) { // clear nodes d.nodes = map[string]string{} for _, host := range d.servers { var scout redis.Conn if scout, err = redis.Dial("tcp", host); err == nil { defer scout.Close() if lines, err := redis.String(scout.Do("CLUSTER", "NODES")); err == nil { for _, line := range strings.Split(lines, "\n") { if strings.TrimSpace(line) != "" { fields := strings.Fields(line) id := fields[0] clusterHost := fields[1] flag := fields[2] prefix := id[0:8] if flag == "myself" { // close main client if it exists if d.client != nil { d.client.Close() } // configure main client if d.client, err = redis.Dial("tcp", host); err == nil { // keep track of selected node d.prefix = prefix } } d.nodes[prefix] = clusterHost } } return err } else { log.Printf("Error returned when querying for cluster nodes on host: %s, exception: %s", host, err) } } else { log.Printf("Error while exploring connection to host: %s, exception: %s", host, err) } } if len(d.nodes) == 0 { err = errors.New("Nodes unavailable") } return err }
func SetKv(key string, value interface{}, rc redis.Conn) error { if rc == nil { rc = redisPool.Get() defer rc.Close() } expireTime := GetRedisTimeUnix() + CACHE_LIFE_SEC bt, err := json.Marshal(&value) if err != nil { return NewErr(err) } err = cmdSetKV.SendHash(rc, key, bt, expireTime) return NewErr(err) }
// subscribe subscribes to the topic for this game // Returns a channel of Messages that can be used to receive messages // Make sure to send it a new redis.Conn. It will handle closing it // when finished. func subscribe(ctx context.Context, con redis.Conn, g *Game) (<-chan *message, error) { lc := "Subscribe" c := make(chan *message) psc := redis.PubSubConn{con} logger.Info(ctx, lc, "Subscribing to topic '%v'", g.ID) err := psc.Subscribe(g.ID) if err != nil { logger.Info(ctx, lc, "Error Subscribing. %v", err) close(c) return c, err } go func(c chan<- *message) { defer con.Close() defer close(c) for { switch v := psc.Receive().(type) { case redis.Message: msg := new(message) err := msg.unmarshalGob(v.Data) if err != nil { logger.Error(ctx, lc, "Could not decode message. Closing channel. %v, %v", v, err) return } logger.Info(ctx, lc, "Received Message. Sending %#v to channel.", msg) c <- msg // special case for LostMessage, since we know to close at this point. if msg.Type == lostMessage { logger.Info(ctx, lc, "Lost Message, Closing Subscribe Pipeline.") return } case error: logger.Error(ctx, lc, "Error processing messages. Closing channel. %v", err) return default: logger.Info(ctx, lc, "Received unknown message. Ignored: %#v", v) } } }(c) return c, nil }
func (p *pool) dial() (redis.Conn, error) { var conn redis.Conn for _, fn := range p.plugins { tmp, err := fn(conn) conn = tmp if err != nil { if conn != nil { conn.Close() } return nil, err } } return conn, nil }
func (this *ReqRedisModule) query(v []int64) (ans []interface{}, err error) { var c redis.Conn c = this.pool.Get() defer c.Close() var tv []interface{} for i := 0; i < len(v); i++ { tv = append(tv, interface{}(v[i])) } var tp interface{} tp, err = c.Do("mget", tv...) if err != nil { utils.FatalLog.Write("request redis fail . err[%s]", err.Error()) return } ans = tp.([]interface{}) return }
// recursive execution method that decrements on every attempt. Tries to handle a number of // redis redirects without getting stuck in a loop func (c *ClusterClient) redirectingDo(redirectsAllowed int, conn redis.Conn, cluster *RedisCluster, cmd RedisCommand) (interface{}, error) { v, err := conn.Do(cmd.cmd, cmd.args...) if err != nil { redirError, ok := parseIfRedir(err) if ok { conn.Close() if redirectsAllowed <= 0 { return nil, errors.New(fmt.Sprintf("exceeded maximum number of Redis cluster redirects: %s", err.Error())) } redirectsAllowed -= 1 return c.handleRedirection(redirectsAllowed, redirError, cluster, cmd) } } conn.Close() return v, err }
func GetKv(key string, out interface{}, rc redis.Conn) (exist bool, err error) { if rc == nil { rc = redisPool.Get() defer rc.Close() } v, err := rc.Do("get", "kv/"+key) if err != nil { return false, NewErr(err) } expireTime := GetRedisTimeUnix() + CACHE_LIFE_SEC var bytes []byte if v != nil { bytes, err = redis.Bytes(v, err) if err != nil { return false, NewErr(err) } //update ttl _, err = rc.Do("zadd", "kvz", expireTime, "kv/"+key) if err != nil { return false, NewErr(err) } } else { //if cache miss, select from db row := kvDB.QueryRow("SELECT v FROM kvs WHERE k=?", key) err = row.Scan(&bytes) if err != nil { if err == sql.ErrNoRows { return false, nil } else { return false, NewErr(err) } } //write to redis err = cmdSetKV.SendHash(rc, key, bytes, expireTime) } //out err = json.Unmarshal(bytes, out) return err == nil, NewErr(err) }
func (p *RedisSvc) DoCmd(cmd string, args ...interface{}) (interface{}, error) { var c redis.Conn var err error if p.pool != nil { c = p.getRedisPool() } else { c, err = redis.Dial("tcp", fmt.Sprintf("%s:%s", p.host, p.port)) if err != nil { return nil, err } } defer c.Close() re, err := c.Do(cmd, args...) if err != nil { return nil, err } return re, nil }
func (r *RedisStorage) Do(commandName string, args ...interface{}) (interface{}, error) { var conn redis.Conn i := r.retry for ; i > 0; i-- { conn = r.pool.Get() err := conn.Err() if err == nil { break } else { //log.Warnf("failed to get conn from pool (%s)", err) } time.Sleep(2 * time.Second) } if i == 0 || conn == nil { return nil, fmt.Errorf("failed to find a useful redis conn") } else { ret, err := conn.Do(commandName, args...) conn.Close() return ret, err } }
// Redis pool dialer. This method is invoked whenever the redis pool allocates a new connection func (s *Redis) dialPoolConnection() (redisDriver.Conn, error) { s.Lock() defer s.Unlock() var err error var wait time.Duration var c redisDriver.Conn s.dialPolicy.ResetAttempts() wait, err = s.dialPolicy.NextRetry() for { c, err = redisDriver.DialTimeout("tcp", s.endpoint, s.connectionTimeout, 0, 0) if err == nil { break } wait, err = s.dialPolicy.NextRetry() if err != nil { s.logger.Printf("Could not connect to REDIS endpoint %s after %d attempt(s)\n", s.endpoint, s.dialPolicy.CurAttempt()) return nil, dial.ErrTimeout } s.logger.Printf("Could not connect to REDIS endpoint %s; retrying in %v\n", s.endpoint, wait) <-time.After(wait) } if s.password != "" { if _, err = c.Do("AUTH", s.password); err != nil { c.Close() return nil, err } } if s.db > 0 { if _, err = c.Do("SELECT", s.db); err != nil { c.Close() return nil, err } } return c, err }
// recvPress Manages receiving Press Events through a go-routine. // Will need it's own Redis connection, that it will close once complete. // Sends io.EOF when the connection closes, and pushes the error into the chan if it // occurs. func recvPress(con redis.Conn, game *Game, player *Request_Player, stream SimonSays_GameServer) <-chan error { lc := "RecvPress" ctx := stream.Context() c := make(chan error, 10) logger.Info(ctx, lc, "Start recieving Press events...") go func() { defer close(c) defer con.Close() for { stop, err := handleColorPress(con, game, player, stream) if err != nil { c <- err return } else if stop { return } } }() return c }