// ping executes a PING command against addr until timeout occurs. func (p *Process) ping(addr string, timeout time.Duration) error { // Default to local process if addr not specified. if addr == "" { addr = fmt.Sprintf("localhost:%s", p.Port) } logger := p.Logger.New("fn", "ping", "addr", addr, "timeout", timeout) logger.Info("sending") timer := time.NewTimer(timeout) defer timer.Stop() ticker := time.NewTicker(checkInterval) defer ticker.Stop() for { // Attempt to ping the server. if ok := func() bool { logger.Info("sending PING") conn, err := redis.Dial("tcp", addr, redis.DialPassword(p.Password), redis.DialConnectTimeout(timeout), redis.DialReadTimeout(timeout), redis.DialWriteTimeout(timeout), ) if err != nil { logger.Error("conn error", "err", err) return false } defer conn.Close() if _, err := conn.Do("PING"); err != nil { logger.Error("error getting upstream status", "err", err) return false } logger.Info("PONG received") return true }(); ok { return nil } select { case <-timer.C: logger.Info("timeout") return ErrTimeout case <-ticker.C: } } }
// RedisInfo executes an INFO command against a Redis server and returns the results. func (p *Process) RedisInfo(addr string, timeout time.Duration) (*RedisInfo, error) { // Default to local process if addr not specified. if addr == "" { addr = fmt.Sprintf("localhost:%s", p.Port) } logger := p.Logger.New("fn", "replInfo", "addr", addr) logger.Info("sending INFO") // Connect to the redis server. conn, err := redis.Dial("tcp", addr, redis.DialPassword(p.Password), redis.DialConnectTimeout(timeout), redis.DialReadTimeout(timeout), redis.DialWriteTimeout(timeout), ) if err != nil { logger.Info("dial error", "err", err) return nil, err } defer conn.Close() // Execute INFO command. reply, err := conn.Do("INFO") if err != nil { logger.Error("info error", "err", err) return nil, err } buf, ok := reply.([]byte) if !ok { logger.Error("info reply type error", "type", fmt.Sprintf("%T", buf)) return nil, fmt.Errorf("unexpected INFO reply format: %T", buf) } // Parse the bulk string reply info a typed object. info, err := ParseRedisInfo(string(buf)) if err != nil { logger.Error("parse info error", "err", err) return nil, fmt.Errorf("parse info: %s", err) } logger.Info("INFO received") return info, nil }