コード例 #1
0
ファイル: slots_test.go プロジェクト: fengshao0907/rpdb
func checkslotsmgrt(t *testing.T, r *bufio.Reader, w *bufio.Writer, c chan error, expect ...interface{}) {
	if len(expect) != 0 {
		req1, err := redis.Decode(r)
		checkerror(t, err, true)
		cmd1, args1, err := redis.ParseArgs(req1)
		checkerror(t, err, cmd1 == "select" && len(args1) == 1)

		checkerror(t, redis.Encode(w, redis.NewString("OK")), true)
		checkerror(t, w.Flush(), true)

		req2, err := redis.Decode(r)
		cmd2, args2, err := redis.ParseArgs(req2)
		checkerror(t, err, cmd2 == "slotsrestore" && len(args2) == len(expect))

		m := make(map[string]*struct {
			key, value string
			ttlms      uint64
		})
		for i := 0; i < len(expect)/3; i++ {
			v := &struct {
				key, value string
				ttlms      uint64
			}{key: expect[i*3].(string), value: expect[i*3+2].(string)}
			v.ttlms, err = ParseUint(expect[i*3+1])
			checkerror(t, err, true)
			m[v.key] = v
		}

		for i := 0; i < len(expect)/3; i++ {
			key := args2[i*3]
			ttlms := args2[i*3+1]
			value := args2[i*3+2]

			v := m[string(key)]
			checkerror(t, nil, v != nil)
			checkerror(t, nil, string(key) == v.key)
			b, err := rdb.DecodeDump(value)
			checkerror(t, err, string(b.(rdb.String)) == v.value)
			x, err := strconv.Atoi(string(ttlms))
			checkerror(t, err, true)
			if v.ttlms == 0 {
				checkerror(t, nil, x == 0)
			} else {
				checkerror(t, nil, x != 0)
				checkerror(t, nil, math.Abs(float64(x)-float64(v.ttlms)) < 500)
			}
		}

		checkerror(t, redis.Encode(w, redis.NewString("OK")), true)
		checkerror(t, w.Flush(), true)
	}

	select {
	case err := <-c:
		checkerror(t, err, true)
	case <-time.After(time.Second):
		checkerror(t, nil, false)
	}
}
コード例 #2
0
ファイル: utils.go プロジェクト: TigerZhang/redis-port
func sendPSyncFullsync(br *bufio.Reader, bw *bufio.Writer) (string, int64, <-chan int64) {
	cmd := redis.NewCommand("psync", "?", -1)
	if err := redis.Encode(bw, cmd, true); err != nil {
		log.PanicError(err, "write psync command failed, fullsync")
	}
	r, err := redis.Decode(br)
	if err != nil {
		log.PanicError(err, "invalid psync response, fullsync")
	}
	if e, ok := r.(*redis.Error); ok {
		log.Panicf("invalid psync response, fullsync, %s", e.Value)
	}
	x, err := redis.AsString(r, nil)
	if err != nil {
		log.PanicError(err, "invalid psync response, fullsync")
	}
	xx := strings.Split(x, " ")
	if len(xx) != 3 || strings.ToLower(xx[0]) != "fullresync" {
		log.Panicf("invalid psync response = '%s', should be fullsync", x)
	}
	v, err := strconv.ParseInt(xx[2], 10, 64)
	if err != nil {
		log.PanicError(err, "parse psync offset failed")
	}
	runid, offset := xx[1], v-1
	return runid, offset, waitRdbDump(br)
}
コード例 #3
0
ファイル: migrate.go プロジェクト: fengshao0907/rpdb
func (c *conn) encodeResp(resp redis.Resp, timeout time.Duration) error {
	if err := c.sock.SetWriteDeadline(time.Now().Add(timeout)); err != nil {
		return err
	}
	if err := redis.Encode(c.w, resp); err != nil {
		return err
	}
	return errors.Trace(c.w.Flush())
}
コード例 #4
0
ファイル: utils.go プロジェクト: fysoft2006/redis-port
func sendPSyncContinue(br *bufio.Reader, bw *bufio.Writer, runid string, offset int64) {
	cmd := redis.NewCommand("psync", runid, offset+2)
	if err := redis.Encode(bw, cmd, true); err != nil {
		log.PanicError(err, "write psync command failed, continue")
	}
	x, err := redis.AsString(redis.Decode(br))
	if err != nil {
		log.PanicError(err, "invalid psync response, continue")
	}
	xx := strings.Split(x, " ")
	if len(xx) != 1 || strings.ToLower(xx[0]) != "continue" {
		log.Panicf("invalid psync response = '%s', should be continue", x)
	}
}
コード例 #5
0
ファイル: slots_test.go プロジェクト: fengshao0907/rpdb
func init() {
	const path = "/tmp/testdb2-rocksdb"
	if err := os.RemoveAll(path); err != nil {
		log.PanicErrorf(err, "remove '%s' failed", path)
	} else {
		conf := rocksdb.NewDefaultConfig()
		if testdb, err := rocksdb.Open(path, conf, true, false); err != nil {
			log.PanicError(err, "open rocksdb failed")
		} else {
			testbl2 = rpdb.New(testdb)
		}
	}
	l, err := net.Listen("tcp", ":0")
	if err != nil {
		log.PanicError(err, "open listen port failed")
	}
	port = l.Addr().(*net.TCPAddr).Port
	go func() {
		server := redis.MustServer(&Handler{})
		for {
			c, err := l.Accept()
			if err != nil {
				log.PanicError(err, "accept socket failed")
			}
			go func() {
				defer c.Close()
				r, w := bufio.NewReader(c), bufio.NewWriter(c)
				s := &fakeSession2{}
				for {
					if req, err := redis.Decode(r); err != nil {
						return
					} else {
						if rsp, err := server.Dispatch(s, req); err != nil {
							return
						} else if rsp != nil {
							if err := redis.Encode(w, rsp); err != nil {
								return
							}
						}
					}
				}
			}()
		}
	}()
}
コード例 #6
0
ファイル: conn.go プロジェクト: fengshao0907/rpdb
func (c *conn) serve(h *Handler) error {
	for {
		if c.timeout != 0 {
			deadline := time.Now().Add(c.timeout)
			if err := c.nc.SetReadDeadline(deadline); err != nil {
				return errors.Trace(err)
			}
		}
		request, err := redis.Decode(c.r)
		if err != nil {
			return err
		}
		h.counters.commands.Add(1)
		response, err := c.dispatch(h, request)
		if err != nil {
			h.counters.commandsFailed.Add(1)
			b, _ := redis.EncodeToBytes(request)
			log.WarnErrorf(err, "handle commands failed, conn = %s, request = '%s'", c.summ, base64.StdEncoding.EncodeToString(b))
		}
		if response == nil {
			continue
		}
		if c.timeout != 0 {
			deadline := time.Now().Add(c.timeout)
			if err := c.nc.SetWriteDeadline(deadline); err != nil {
				return errors.Trace(err)
			}
		}
		if err := redis.Encode(c.w, response); err != nil {
			return err
		}
		if err := errors.Trace(c.w.Flush()); err != nil {
			return err
		}
	}
}
コード例 #7
0
ファイル: utils.go プロジェクト: TigerZhang/redis-port
func sendPSyncAck(bw *bufio.Writer, offset int64) error {
	cmd := redis.NewCommand("replconf", "ack", offset)
	return redis.Encode(bw, cmd, true)
}