func (s *Server) Dispatch(arg0 interface{}, respArg resp.Resp) (resp.Resp, error) { if cmd, args, err := resp.ParseArgs(respArg); err != nil { return nil, err } else if f := s.t[cmd]; f == nil { return nil, errors.Errorf("unknown command '%s'", cmd) } else { return f(arg0, args...) } }
func (cmd *cmdRestore) RestoreCommand(reader *bufio.Reader, slave string, nsize int64) { var forward, nbypass atomic2.Int64 c := openNetConn(slave) defer c.Close() writer := bufio.NewWriterSize(c, WriterBufferSize) defer flushWriter(writer) discard := bufio.NewReaderSize(c, ReaderBufferSize) go func() { var bypass bool = false for { resp := redis.MustDecode(reader) if cmd, args, err := redis.ParseArgs(resp); err != nil { log.PanicError(err, "parse command arguments failed") } else if cmd != "ping" { if cmd == "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 { nbypass.Incr() continue } } redis.MustEncode(writer, resp) flushWriter(writer) forward.Incr() redis.MustDecode(discard) } }() for { lastForward := forward.Get() lastByPass := nbypass.Get() time.Sleep(time.Second) log.Infof("restore: +forward=%-6d +bypass=%-6d\n", forward.Get()-lastForward, nbypass.Get()-lastByPass) } }
func (c *conn) dispatch(h *Handler, request redis.Resp) (redis.Resp, error) { cmd, args, err := redis.ParseArgs(request) if err != nil { return toRespError(err) } // check cmd first, then auth if f := h.htable[cmd]; f == nil { return toRespErrorf("unknown command %s", cmd) } else { if len(h.config.Auth) > 0 && !c.authenticated && strings.ToLower(cmd) != "auth" { return toRespErrorf("NOAUTH Authentication required") } return f(c, args) } }
func (c *conn) dispatch(h *Handler, request redis.Resp) (redis.Resp, error) { cmd, args, err := redis.ParseArgs(request) if err != nil { return toRespError(err) } // check cmd first, then auth if f := h.htable[cmd]; f == nil { return toRespErrorf("unknown command %s", cmd) } else { if len(h.config.Auth) > 0 && !c.authenticated && strings.ToLower(cmd) != "auth" { return toRespErrorf("NOAUTH Authentication required") } masterAddr := c.h.masterAddr.Get() if len(masterAddr) > 0 && f.flag&CmdWrite > 0 && !c.isSyncing { // we are a slave, so can not receive any write operations except from master in syncing return toRespErrorf("READONLY You can't write against a read only slave.") } return f.f(c, args) } }
func (cmd *cmdSync) SyncCommand(reader *bufio.Reader, slave string) { var forward, nbypass atomic2.Int64 c := openNetConn(slave) defer c.Close() writer := bufio.NewWriterSize(c, WriterBufferSize) defer flushWriter(writer) go func() { p := make([]byte, ReaderBufferSize) for { cnt := iocopy(c, ioutil.Discard, p, len(p)) cmd.nrecv.Add(int64(cnt)) } }() var mu sync.Mutex go func() { for { time.Sleep(time.Second) mu.Lock() flushWriter(writer) mu.Unlock() } }() go func() { var bypass bool = false for { resp := redis.MustDecode(reader) if cmd, args, err := redis.ParseArgs(resp); err != nil { log.PanicError(err, "parse command arguments failed") } else if cmd != "ping" { if cmd == "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 { nbypass.Incr() continue } } mu.Lock() redis.MustEncode(writer, resp) mu.Unlock() forward.Incr() } }() for { lastForward := forward.Get() lastByPass := nbypass.Get() lastRead := cmd.nread.Get() lastRecv := cmd.nrecv.Get() time.Sleep(time.Second) log.Infof("sync: +forward=%-6d +bypass=%-6d +read=%-9d +recv=%-9d\n", forward.Get()-lastForward, nbypass.Get()-lastByPass, cmd.nread.Get()-lastRead, cmd.nrecv.Get()-lastRecv) } }
func (s *testStoreSuite) checkSlotsMgrt(c *C, r *bufio.Reader, w *bufio.Writer, cc chan error, expect ...interface{}) { if len(expect) != 0 { req1, err := redis.Decode(r) c.Assert(err, IsNil) cmd1, args1, err := redis.ParseArgs(req1) c.Assert(err, IsNil) c.Assert(cmd1, Equals, "select") c.Assert(len(args1), Equals, 1) err = redis.Encode(w, redis.NewString("OK")) c.Assert(err, IsNil) err = w.Flush() c.Assert(err, IsNil) req2, err := redis.Decode(r) cmd2, args2, err := redis.ParseArgs(req2) c.Assert(err, IsNil) c.Assert(cmd2, Equals, "slotsrestore") c.Assert(len(args2), Equals, 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]) c.Assert(err, IsNil) 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)] c.Assert(v, NotNil) c.Assert(string(key), Equals, v.key) b, err := rdb.DecodeDump(value) c.Assert(err, IsNil) c.Assert(string(b.(rdb.String)), Equals, v.value) x, err := strconv.Atoi(string(ttlms)) c.Assert(err, IsNil) if v.ttlms == 0 { c.Assert(x, Equals, 0) } else { c.Assert(x, Not(Equals), 0) c.Assert(math.Abs(float64(x)-float64(v.ttlms)) < 1000, Equals, true) } } err = redis.Encode(w, redis.NewString("OK")) c.Assert(err, IsNil) err = w.Flush() c.Assert(err, IsNil) } select { case err := <-cc: c.Assert(err, IsNil) case <-time.After(time.Second): c.Fatal("timeout error") } }