Пример #1
0
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...)
	}
}
Пример #2
0
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)
	}
}
Пример #3
0
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)
	}
}
Пример #4
0
Файл: conn.go Проект: CowLeo/qdb
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)
	}
}
Пример #5
0
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)
	}
}
Пример #6
0
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")
	}
}