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 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) }
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()) }
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) } }
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 } } } } }() } }() }
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 } } }
func sendPSyncAck(bw *bufio.Writer, offset int64) error { cmd := redis.NewCommand("replconf", "ack", offset) return redis.Encode(bw, cmd, true) }