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) } }
func (cmd *cmdSync) SyncCommand(reader *bufio.Reader, target, passwd string) { c := openNetConn(target, passwd) defer c.Close() writer := bufio.NewWriterSize(stats.NewCountWriter(c, &cmd.wbytes), WriterBufferSize) defer flushWriter(writer) go func() { p := make([]byte, ReaderBufferSize) for { iocopy(c, ioutil.Discard, p, len(p)) } }() go func() { var bypass bool = false for { resp := redis.MustDecode(reader) if scmd, args, err := redis.ParseArgs(resp); err != nil { log.PanicError(err, "parse command arguments failed") } else if scmd != "ping" { if scmd == "select" { if len(args) != 1 { log.Panicf("select command len(args) = %d", len(args)) } s := string(args[0]) n, err := parseInt(s, MinDB, MaxDB) if err != nil { log.PanicErrorf(err, "parse db = %s failed", s) } bypass = !acceptDB(uint32(n)) } if bypass { cmd.nbypass.Incr() continue } } cmd.forward.Incr() redis.MustEncode(writer, resp) flushWriter(writer) } }() for lstat := cmd.Stat(); ; { time.Sleep(time.Second) nstat := cmd.Stat() var b bytes.Buffer fmt.Fprintf(&b, "sync: ") fmt.Fprintf(&b, " +forward=%-6d", nstat.forward-lstat.forward) fmt.Fprintf(&b, " +nbypass=%-6d", nstat.nbypass-lstat.nbypass) fmt.Fprintf(&b, " +nbytes=%d", nstat.wbytes-lstat.wbytes) log.Info(b.String()) lstat = nstat } }
func (c *conn) dispatch(h *Handler, request redis.Resp) (redis.Resp, error) { cmd, args, err := redis.ParseArgs(request) if err != nil { return toRespError(err) } if f := h.htable[cmd]; f == nil { return toRespErrorf("unknown command %s", cmd) } else { return f(c, args...) } }