コード例 #1
0
ファイル: repl_test.go プロジェクト: vebin/reborn
func (s *testReplSuite) testReplication(c *C, master testReplNode, slave testReplNode) {
	// first let both stop replication
	s.doCmdMustOK(c, master.Port(), "SLAVEOF", "NO", "ONE")
	s.doCmdMustOK(c, slave.Port(), "SLAVEOF", "NO", "ONE")

	s.doCmdMustOK(c, master.Port(), "SET", "a", "100")

	offset := int64(-1)
	// slaveof, will do full sync first, must support psync
	nc := slave.Slaveof(c, master.Port())
	defer nc.Close(c)

	s.waitAndCheckSyncOffset(c, slave, offset)

	resp := s.doCmd(c, slave.Port(), "GET", "a")
	c.Assert(slave.SyncOffset(c), Not(Equals), int64(-1))
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("100"))

	s.doCmdMustOK(c, master.Port(), "SET", "b", "100")

	time.Sleep(500 * time.Millisecond)
	resp = s.doCmd(c, slave.Port(), "GET", "b")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("100"))

	s.doCmdMustOK(c, master.Port(), "SET", "c", "")

	time.Sleep(500 * time.Millisecond)
	resp = s.doCmd(c, slave.Port(), "GET", "c")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString(""))

	offset = slave.SyncOffset(c)
	// now close replication connection
	nc.Close(c)
	s.doCmdMustOK(c, master.Port(), "SET", "b", "1000")

	s.doCmdMustOK(c, master.Port(), "SET", "c", "123")

	s.waitAndCheckSyncOffset(c, slave, offset)

	resp = s.doCmd(c, slave.Port(), "GET", "b")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("1000"))

	resp = s.doCmd(c, slave.Port(), "GET", "c")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("123"))

	s.checkRole(c, master.Port(), "master")
	s.checkRole(c, slave.Port(), "slave")

	s.doCmdMustOK(c, slave.Port(), "SLAVEOF", "NO", "ONE")
	s.doCmdMustOK(c, master.Port(), "SLAVEOF", "NO", "ONE")

	s.checkRole(c, master.Port(), "master")
	s.checkRole(c, slave.Port(), "master")
}
コード例 #2
0
ファイル: hash.go プロジェクト: cuiwm/reborn
// HINCRBYFLOAT key field delta
func HIncrByFloatCmd(s Session, args [][]byte) (redis.Resp, error) {
	if v, err := s.Store().HIncrByFloat(s.DB(), args); err != nil {
		return toRespError(err)
	} else {
		return redis.NewBulkBytesWithString(store.FormatFloatString(v)), nil
	}
}
コード例 #3
0
ファイル: repl.go プロジェクト: CowLeo/qdb
// ROLE
func RoleCmd(s Session, args [][]byte) (redis.Resp, error) {
	if len(args) != 0 {
		return toRespErrorf("len(args) = %d, expect = 0", len(args))
	}

	c, _ := s.(*conn)
	if c == nil {
		return nil, errors.New("invalid connection")
	}

	ay := redis.NewArray()
	if masterAddr := c.h.masterAddr.Get(); masterAddr == "" {
		// master
		ay.Append(redis.NewBulkBytesWithString("master"))
		c.h.repl.RLock()
		defer c.h.repl.RUnlock()

		ay.Append(redis.NewInt(c.h.repl.masterOffset))
		slaves := redis.NewArray()
		for slave, _ := range c.h.repl.slaves {
			a := redis.NewArray()
			if addr := slave.nc.RemoteAddr(); addr == nil {
				continue
			} else {
				a.Append(redis.NewBulkBytesWithString(strings.Split(addr.String(), ":")[0]))
			}
			a.Append(redis.NewBulkBytesWithString(fmt.Sprintf("%d", slave.listeningPort.Get())))
			a.Append(redis.NewBulkBytesWithString(fmt.Sprintf("%d", slave.syncOffset.Get())))
			slaves.Append(a)
		}

		ay.Append(slaves)
	} else {
		// slave
		ay.Append(redis.NewBulkBytesWithString("slave"))
		seps := strings.Split(masterAddr, ":")
		if len(seps) == 2 {
			port, err := strconv.ParseInt(seps[1], 10, 16)
			if err != nil {
				return toRespError(err)
			}
			ay.Append(redis.NewBulkBytesWithString(seps[0]))
			ay.Append(redis.NewInt(int64(port)))
		} else {
			return toRespErrorf("invalid master addr, must ip:port, but %s", masterAddr)
		}
		ay.Append(redis.NewBulkBytesWithString(c.h.masterConnState.Get()))
		ay.Append(redis.NewInt(c.h.syncOffset.Get()))
	}
	return ay, nil
}
コード例 #4
0
ファイル: repl_test.go プロジェクト: CowLeo/qdb
func (s *testReplSuite) testReplication(c *C, master testReplNode, slave testReplNode) {
	// first let both stop replication
	s.doCmdMustOK(c, master.Port(), "SLAVEOF", "NO", "ONE")
	s.doCmdMustOK(c, slave.Port(), "SLAVEOF", "NO", "ONE")

	s.doCmdMustOK(c, master.Port(), "SET", "a", "100")

	offset := int64(-1)
	// slaveof, will do full sync first, must support psync
	nc := slave.Slaveof(c, master.Port())
	defer nc.Close(c)

	s.waitAndCheckSyncOffset(c, slave, offset)

	resp := s.doCmd(c, slave.Port(), "GET", "a")
	c.Assert(slave.SyncOffset(c), Not(Equals), int64(-1))
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("100"))

	// write to a slave, must error
	resp = s.doCmd(c, slave.Port(), "SET", "e", "1")
	c.Assert(resp, FitsTypeOf, (*redis.Error)(nil))
	c.Assert(resp.(*redis.Error).Value, Matches, "READONLY.*")

	s.doCmdMustOK(c, master.Port(), "SET", "b", "100")

	time.Sleep(500 * time.Millisecond)
	resp = s.doCmd(c, slave.Port(), "GET", "b")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("100"))

	s.doCmdMustOK(c, master.Port(), "SET", "c", "")

	// set another value with TTL
	s.doCmdMustOK(c, master.Port(), "SET", "ttl_key", "1", "PX", 100)

	time.Sleep(500 * time.Millisecond)
	resp = s.doCmd(c, slave.Port(), "GET", "c")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString(""))

	// get expired key to let master force delete it
	resp = s.doCmd(c, master.Port(), "GET", "ttl_key")
	c.Assert(resp, DeepEquals, redis.NewBulkBytes(nil))

	time.Sleep(500 * time.Millisecond)

	// the key must be deleted from master repliction
	resp = s.doCmd(c, slave.Port(), "GET", "ttl_key")
	c.Assert(resp, DeepEquals, redis.NewBulkBytes(nil))

	offset = slave.SyncOffset(c)
	// now close replication connection
	nc.Close(c)
	s.doCmdMustOK(c, master.Port(), "SET", "b", "1000")

	s.doCmdMustOK(c, master.Port(), "SET", "c", "123")

	s.waitAndCheckSyncOffset(c, slave, offset)

	resp = s.doCmd(c, slave.Port(), "GET", "b")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("1000"))

	resp = s.doCmd(c, slave.Port(), "GET", "c")
	c.Assert(resp, DeepEquals, redis.NewBulkBytesWithString("123"))

	s.checkRole(c, master.Port(), "master")
	s.checkRole(c, slave.Port(), "slave")

	s.doCmdMustOK(c, slave.Port(), "SLAVEOF", "NO", "ONE")
	s.doCmdMustOK(c, master.Port(), "SLAVEOF", "NO", "ONE")

	s.checkRole(c, master.Port(), "master")
	s.checkRole(c, slave.Port(), "master")
}