Beispiel #1
0
func (bc *BackendConn) verifyAuth(c *redis.Conn) error {
	if bc.passwd == "" {
		return nil
	}
	resp := redis.NewArray([]*redis.Resp{
		redis.NewBulkBytes([]byte("AUTH")),
		redis.NewBulkBytes([]byte(bc.passwd)),
	})

	if err := c.Writer.Encode(resp, true); err != nil {
		return err
	}

	resp, err := c.Reader.Decode()
	if err != nil {
		return err
	}
	if resp == nil {
		return errors.New(fmt.Sprintf("error resp: nil response"))
	}
	if resp.IsError() {
		return errors.New(fmt.Sprintf("error resp: %s", resp.Value))
	}
	if resp.IsString() {
		return nil
	} else {
		return errors.New(fmt.Sprintf("error resp: should be string, but got %s", resp.Type))
	}
}
Beispiel #2
0
func (s *Slot) slotsmgrt(r *Request, key []byte) error {
	if len(key) == 0 || s.migrate.bc == nil {
		return nil
	}
	m := &Request{
		Owner: r.Owner,
		Wait:  &sync.WaitGroup{},
		Resp: redis.NewArray([]*redis.Resp{
			redis.NewBulkBytes([]byte("SLOTSMGRTTAGONE")),
			redis.NewBulkBytes(s.backend.host),
			redis.NewBulkBytes(s.backend.port),
			redis.NewBulkBytes([]byte("3000")),
			redis.NewBulkBytes(key),
		}),
	}
	m.Wait.Add(1)

	s.migrate.bc.PushBack(m)

	m.Wait.Wait()

	resp, err := m.Response.Resp, m.Response.Err
	if err != nil {
		return err
	}
	if resp == nil {
		return ErrRespIsRequired
	}
	if resp.IsError() {
		return errors.New(fmt.Sprintf("error resp: %s", resp.Value))
	}
	if resp.IsInt() {
		log.Debugf("slot-%04d migrate from %s to %s: key = %s, resp = %s",
			s.Id, s.migrate.from, s.backend.addr, key, resp.Value)
		return nil
	} else {
		return errors.New(fmt.Sprintf("error resp: should be integer, but got %s", resp.Type))
	}
}
Beispiel #3
0
func (bc *BackendConn) KeepAlive() bool {
	if len(bc.input) != 0 {
		return false
	}
	r := &Request{
		Resp: redis.NewArray([]*redis.Resp{
			redis.NewBulkBytes([]byte("PING")),
		}),
	}

	select {
	case bc.input <- r:
		return true
	default:
		return false
	}
}
Beispiel #4
0
func TestBackend(t *testing.T) {
	l, err := net.Listen("tcp", "127.0.0.1:0")
	assert.MustNoError(err)
	defer l.Close()

	addr := l.Addr().String()
	reqc := make(chan *Request, 16384)
	go func() {
		bc := NewBackendConn(addr)
		defer bc.Close()
		defer close(reqc)
		var resp = redis.NewBulkBytes(make([]byte, 4096))
		for i := 0; i < cap(reqc); i++ {
			r := &Request{
				Resp: resp,
				Wait: &sync.WaitGroup{},
			}
			r.Wait.Add(1)
			bc.PushBack(r)
			reqc <- r
		}
	}()

	go func() {
		c, err := l.Accept()
		assert.MustNoError(err)
		defer c.Close()
		conn := redis.NewConn(c)
		time.Sleep(time.Millisecond * 300)
		for i := 0; i < cap(reqc); i++ {
			_, err := conn.Reader.Decode()
			assert.MustNoError(err)
			resp := redis.NewString([]byte(strconv.Itoa(i)))
			assert.MustNoError(conn.Writer.Encode(resp, true))
		}
	}()

	var n int
	for r := range reqc {
		r.Wait.Wait()
		assert.Must(string(r.Response.Resp.Value) == strconv.Itoa(n))
		n++
	}
	assert.Must(n == cap(reqc))
}
Beispiel #5
0
func TestGetOpStr(t *testing.T) {
	var m = map[string]string{
		"get":     "GET",
		"aBc":     "ABC",
		"おはよ":     "おはよ",
		"ni hao!": "NI HAO!",
		"":        "",
	}
	for k, v := range m {
		resp := redis.NewArray([]*redis.Resp{redis.NewBulkBytes([]byte(k))})
		s, err := getOpStr(resp)
		if v != "" {
			assert.MustNoError(err)
			assert.Must(s == v)
		} else {
			assert.Must(err != nil)
		}
	}
}
Beispiel #6
0
func TestGetOpStrCmd(t *testing.T) {
	var m = map[string]string{
		"del":              "DEL",
		"dump":             "DUMP",
		"exists":           "EXISTS",
		"expire":           "EXPIRE",
		"expireat":         "EXPIREAT",
		"persist":          "PERSIST",
		"pexpire":          "PEXPIRE",
		"pexpireat":        "PEXPIREAT",
		"pttl":             "PTTL",
		"restore":          "RESTORE",
		"sort":             "SORT",
		"ttl":              "TTL",
		"type":             "TYPE",
		"append":           "APPEND",
		"bitcount":         "BITCOUNT",
		"decr":             "DECR",
		"decrby":           "DECRBY",
		"get":              "GET",
		"getbit":           "GETBIT",
		"getrange":         "GETRANGE",
		"getset":           "GETSET",
		"incr":             "INCR",
		"incrby":           "INCRBY",
		"incrbyfloat":      "INCRBYFLOAT",
		"mget":             "MGET",
		"mset":             "MSET",
		"psetex":           "PSETEX",
		"set":              "SET",
		"setbit":           "SETBIT",
		"setex":            "SETEX",
		"setnx":            "SETNX",
		"setrange":         "SETRANGE",
		"strlen":           "STRLEN",
		"hdel":             "HDEL",
		"hexists":          "HEXISTS",
		"hget":             "HGET",
		"hgetall":          "HGETALL",
		"hincrby":          "HINCRBY",
		"hincrbyfloat":     "HINCRBYFLOAT",
		"hkeys":            "HKEYS",
		"hlen":             "HLEN",
		"hmget":            "HMGET",
		"hmset":            "HMSET",
		"hset":             "HSET",
		"hsetnx":           "HSETNX",
		"hvals":            "HVALS",
		"hscan":            "HSCAN",
		"lindex":           "LINDEX",
		"linsert":          "LINSERT",
		"llen":             "LLEN",
		"lpop":             "LPOP",
		"lpush":            "LPUSH",
		"lpushx":           "LPUSHX",
		"lrange":           "LRANGE",
		"lrem":             "LREM",
		"lset":             "LSET",
		"ltrim":            "LTRIM",
		"rpop":             "RPOP",
		"rpoplpush":        "RPOPLPUSH",
		"rpush":            "RPUSH",
		"rpushx":           "RPUSHX",
		"sadd":             "SADD",
		"scard":            "SCARD",
		"sdiff":            "SDIFF",
		"sdiffstore":       "SDIFFSTORE",
		"sinter":           "SINTER",
		"sinterstore":      "SINTERSTORE",
		"sismember":        "SISMEMBER",
		"smembers":         "SMEMBERS",
		"smove":            "SMOVE",
		"spop":             "SPOP",
		"srandmember":      "SRANDMEMBER",
		"srem":             "SREM",
		"sunion":           "SUNION",
		"sunionstore":      "SUNIONSTORE",
		"sscan":            "SSCAN",
		"zadd":             "ZADD",
		"zcard":            "ZCARD",
		"zcount":           "ZCOUNT",
		"zincrby":          "ZINCRBY",
		"zinterstore":      "ZINTERSTORE",
		"zlexcount":        "ZLEXCOUNT",
		"zrange":           "ZRANGE",
		"zrangebylex":      "ZRANGEBYLEX",
		"zrangebyscore":    "ZRANGEBYSCORE",
		"zrank":            "ZRANK",
		"zrem":             "ZREM",
		"zremrangebylex":   "ZREMRANGEBYLEX",
		"zremrangebyrank":  "ZREMRANGEBYRANK",
		"zremrangebyscore": "ZREMRANGEBYSCORE",
		"zrevrange":        "ZREVRANGE",
		"zrevrangebyscore": "ZREVRANGEBYSCORE",
		"zrevrank":         "ZREVRANK",
		"zscore":           "ZSCORE",
		"zunionstore":      "ZUNIONSTORE",
		"zscan":            "ZSCAN",
		"pfadd":            "PFADD",
		"pfcount":          "PFCOUNT",
		"pfmerge":          "PFMERGE",
		"eval":             "EVAL",
		"evalsha":          "EVALSHA",
	}
	for k, v := range m {
		resp := redis.NewArray([]*redis.Resp{redis.NewBulkBytes([]byte(k))})
		s, err := getOpStr(resp)
		assert.MustNoError(err)
		assert.Must(s == v)
	}
}