コード例 #1
0
ファイル: strings.go プロジェクト: brianbrunner/omg
func init() {

	store.RegisterStoreType(StringType)

	store.DefaultDBManager.AddFuncWithSideEffects("append", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		if ok {
			str, _ := elem.Value.(string)
			str += args[1]
			elem.Value = str
			return reply.IntReply(len(str))
		} else {
			db.StoreSet(args[0], &data.Entry{args[1], StringType})
			return reply.IntReply(len(args[1]))
		}
	})

	bitCount := []uint8{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
		1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
		1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
		2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
		1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
		2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
		2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
		3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
		1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
		2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
		2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
		3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
		2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
		3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
		3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
		4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}

	store.DefaultDBManager.AddFuncWithSideEffects("bitcount", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		if ok {
			byte_arr, _ := elem.Value.([]byte)
			c := 0
			for _, c := range byte_arr {
				c += bitCount[c]
			}
			return reply.IntReply(c)
		} else {
			return reply.IntReply(0)
		}
	})

	store.DefaultDBManager.AddFuncWithSideEffects("decr", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		var num int
		if ok {
			str, _ := elem.Value.(string)
			num, err := strconv.Atoi(str)
			if err != nil {
				panic(err)
			}
			num -= 1
			elem.Value = fmt.Sprintf("%d", num)
		} else {
			num = -1
			db.StoreSet(args[0], &data.Entry{"-1", StringType})
		}
		return reply.IntReply(num)
	})

	store.DefaultDBManager.AddFuncWithSideEffects("decrby", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		var num int

		decrby, err := strconv.Atoi(args[1])
		if err != nil {
			panic(err)
		}

		if ok {
			str, _ := elem.Value.(string)

			num, err := strconv.Atoi(str)
			if err != nil {
				panic(err)
			}

			num -= decrby
			elem.Value = fmt.Sprintf("%d", num)
		} else {
			str := fmt.Sprintf("-%d", decrby)
			db.StoreSet(args[0], &data.Entry{str, StringType})
		}
		println(num)
		return reply.IntReply(num)
	})

	store.DefaultDBManager.AddFuncWithSideEffects("incr", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		var num int
		if ok {
			str, _ := elem.Value.(string)
			num, err := strconv.Atoi(str)
			if err != nil {
				panic(err)
			}
			num += 1
			elem.Value = fmt.Sprintf("%d", num)
		} else {
			num = 1
			db.StoreSet(args[0], &data.Entry{"-1", StringType})
		}
		return reply.IntReply(num)
	})

	store.DefaultDBManager.AddFuncWithSideEffects("incrby", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		var num int

		decrby, err := strconv.Atoi(args[1])
		if err != nil {
			panic(err)
		}

		if ok {
			str, _ := elem.Value.(string)

			num, err := strconv.Atoi(str)
			if err != nil {
				panic(err)
			}

			num += decrby
			elem.Value = fmt.Sprintf("%d", num)
		} else {
			str := fmt.Sprintf("%d", decrby)
			db.StoreSet(args[0], &data.Entry{str, StringType})
		}
		println(num)
		return reply.IntReply(num)
	})

	store.DefaultDBManager.AddFunc("get", func(db *store.DB, args []string) string {
		elem, ok, err := db.StoreGet(args[0], StringType)
		if err != nil {
			return reply.ErrorReply(err)
		}
		if ok {
			str := elem.GetString()
			return reply.BulkReply(str)
		} else {
			return reply.NilReply
		}
	})

	store.DefaultDBManager.AddFunc("getset", func(db *store.DB, args []string) string {
		elem, ok, err := db.StoreGet(args[0], StringType)
		if err != nil {
			return reply.ErrorReply(err)
		}
		if ok {
			str := elem.GetString()
			elem.Value = args[1]
			return reply.BulkReply(str)
		} else {
			db.StoreSet(args[0], &data.Entry{args[1], StringType})
			return reply.NilReply
		}
	})

	store.DefaultDBManager.AddFuncWithSideEffects("psetex", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)

		millis, err := strconv.Atoi(args[1])
		if err != nil {
			panic(err)
		}

		db.ExpiryRecord[args[0]] = store.Milliseconds() + uint64(millis)

		if ok {
			elem.Value = args[2]
		} else {
			db.StoreSet(args[0], &data.Entry{args[2], StringType})
		}

		return reply.OKReply
	})

	store.DefaultDBManager.AddFuncWithSideEffects("setex", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)

		seconds, err := strconv.Atoi(args[1])
		if err != nil {
			panic(err)
		}

		db.ExpiryRecord[args[0]] = store.Milliseconds() + uint64(seconds)*1000

		if ok {
			elem.Value = args[2]
		} else {
			db.StoreSet(args[0], &data.Entry{args[2], StringType})
		}

		return reply.OKReply
	})

	store.DefaultDBManager.AddFuncWithSideEffects("set", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], StringType)
		if ok {
			elem.Value = args[1]
		} else {
			db.StoreSet(args[0], &data.Entry{args[1], StringType})
		}
		return reply.OKReply
	})

	store.DefaultDBManager.AddFuncWithSideEffects("setnx", func(db *store.DB, args []string) string {
		s := args[0]
		_, ok, _ := db.StoreGet(s, StringType)
		if ok {
			return reply.IntReply(0)
		}
		db.StoreSet(s, &data.Entry{args[1], StringType})
		return reply.IntReply(1)
	})

	store.DefaultDBManager.AddFunc("strlen", func(db *store.DB, args []string) string {
		elem, ok, err := db.StoreGet(args[0], StringType)
		if err != nil {
			return reply.ErrorReply(err)
		}
		if ok {
			str := elem.GetString()
			return reply.IntReply(len(str))
		} else {
			return reply.IntReply(0)
		}
	})

}
コード例 #2
0
ファイル: server.go プロジェクト: brianbrunner/omg
func init() {

	store.DefaultDBManager.AddFunc("select", func(db *store.DB, args []string) string {
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("info", func(db *store.DB, args []string) string {
		return reply.BulkReply("# Server\r\nredis_version:2.6.7\r\n")
	})

	store.DefaultDBManager.AddFunc("meminuse", func(db *store.DB, args []string) string {
		return reply.IntReply(int(store.MemInUse()))
	})

	store.DefaultDBManager.AddFunc("objectsinuse", func(db *store.DB, args []string) string {
		var memProfiles []runtime.MemProfileRecord
		n, _ := runtime.MemProfile(memProfiles, false)
		memProfiles = make([]runtime.MemProfileRecord, n)
		n, _ = runtime.MemProfile(memProfiles, false)

		objects := int64(0)
		for _, prof := range memProfiles {
			objects += prof.InUseObjects()
		}

		return reply.IntReply(int(objects))
	})

	store.DefaultDBManager.AddFunc("gc", func(db *store.DB, args []string) string {
		runtime.GC()
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("freeosmemory", func(db *store.DB, args []string) string {
		debug.FreeOSMemory()
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("save", func(db *store.DB, args []string) string {
		err := db.SaveToDiskSync()
		if err != nil {
			return reply.ErrorReply(err)
		} else {
			return reply.OKReply
		}
	})

	store.DefaultDBManager.AddFunc("bgsave", func(db *store.DB, args []string) string {
		store.DefaultDBManager.SaveToDiskAsync(nil)
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("__end_save_mode__", func(db *store.DB, args []string) string {
		db.EndSaveMode()
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("dbsize", func(db *store.DB, args []string) string {
		return reply.IntReply(store.DefaultDBManager.DBSize())
	})

	store.DefaultDBManager.AddFunc("lastdump", func(db *store.DB, args []string) string {
		elem, ok, _ := db.StoreGet(args[0], data.Any)
		if ok {
			return reply.IntReply(int(elem.LastDump()))
		} else {
			return reply.NilReply
		}
	})

	store.DefaultDBManager.AddFunc("lastdumpdb", func(db *store.DB, args []string) string {
		return reply.IntReply(int(db.LastDump()))
	})

	store.DefaultDBManager.AddFunc("flush", func(db *store.DB, args []string) string {
		db.Flush()
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("keysperdb", func(db *store.DB, args []string) string {
		var w reply.MultiBulkWriter
		dbs := store.DefaultDBManager.GetDBs()
		w.WriteCount(len(dbs))
		for _, db := range dbs {
			w.WriteString(fmt.Sprintf("%d", len(db.Store)))
		}
		return w.String()
	})

}
コード例 #3
0
ファイル: feed.go プロジェクト: brianbrunner/omg
func init() {

	gob.Register(&Post{})
	gob.Register(&Feed{})

	store.RegisterStoreType(FeedType)

	store.DefaultDBManager.AddFuncWithSideEffects("feedcap", func(db *store.DB, args []string) string {
		s := args[0]
		cap, err := strconv.Atoi(args[1])
		if err != nil {
			return reply.ErrorReply(err)
		}
		e, ok, _ := db.StoreGet(s, FeedType)
		if ok {
			if f, ok := e.Value.(*Feed); ok {
				f.Capacity = cap
				return reply.OKReply
			} else {
				return reply.ErrorReply("Type Mismatch")
			}
		} else {
			f := &Feed{s, cap, 0, make([]*Post, 0)}
			db.StoreSet(s, &data.Entry{f, FeedType})
		}
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("feedget", func(db *store.DB, args []string) string {
		if e, ok, _ := db.StoreGet(args[0], FeedType); ok {
			if f, ok := e.Value.(*Feed); ok {
				cap_str := fmt.Sprintf("%d", f.Capacity)
				var rep reply.MultiBulkWriter
				rep.WriteCount(2)
				rep.WriteString(f.Name)
				rep.WriteString(cap_str)
				return rep.String()
			} else {
				return "-ERR Type mismatch\r\n"
			}
		} else {
			return reply.NilReply
		}
	})

	store.DefaultDBManager.AddFuncWithSideEffects("feedpost", func(db *store.DB, args []string) string {
		e, ok, _ := db.StoreGet(args[0], FeedType)
		if !ok {
			s := args[0]
			f := &Feed{s, -1, 0, make([]*Post, 0)}
			e = &data.Entry{f, FeedType}
			db.StoreSet(s, e)
		}
		if f, ok := e.Value.(*Feed); ok {
			timestamp := store.Milliseconds()
			if timestamp == f.LastTimestamp {
				timestamp += 1
			}
			f.LastTimestamp = timestamp
			p := &Post{args[1], args[2], timestamp, 0, make(map[string]string)}
			f.Posts = append(f.Posts, p)
			return reply.OKReply
		} else {
			return reply.ErrorReply("Type mismatch")
		}
	})

	store.DefaultDBManager.AddFunc("feedposts", func(db *store.DB, args []string) string {
		if e, ok, _ := db.StoreGet(args[0], FeedType); ok {
			if f, ok := e.Value.(*Feed); ok {
				post_count := len(f.Posts)
				offset := 0
				count := post_count
				if len(args) == 3 {

					var err error
					offset, err = strconv.Atoi(args[1])
					if err != nil {
						panic(err)
					}

					count, err = strconv.Atoi(args[2])
					if err != nil {
						panic(err)
					}

				}

				if offset >= post_count {
					return reply.NilReply
				}

				if offset+count > post_count {
					count = post_count - offset
				}

				var rep reply.MultiBulkWriter
				rep.WriteCount(3 * post_count)
				for i := post_count - offset; i >= post_count-offset-count; i-- {
					p := f.Posts[i]
					timestamp_str := fmt.Sprintf("%d", p.Timestamp)
					rep.WriteString(p.Author)
					rep.WriteString(p.Body)
					rep.WriteString(timestamp_str)
				}
				return rep.String()
			} else {
				return reply.ErrorReply("Type mismatch")
			}
		} else {
			return reply.NilReply
		}
	})

	store.DefaultDBManager.AddFunc("feedlen", func(db *store.DB, args []string) string {
		if e, ok, _ := db.StoreGet(args[0], FeedType); ok {
			if f, ok := e.Value.(*Feed); ok {
				return reply.IntReply(len(f.Posts))
			}
		}
		return reply.NilReply
	})

	//store.DefaultDBManager.AddFuncWithSideEffects("feedlike", func (db *store.DB, args []string) string {
	//})
}
コード例 #4
0
ファイル: user.go プロジェクト: brianbrunner/omg
func init() {

	gob.Register(&User{})

	store.RegisterStoreType(UserType)

	store.DefaultDBManager.AddFuncWithSideEffects("useradd", func(db *store.DB, args []string) string {
		s := args[0]
		_, ok, _ := db.StoreGet(s, UserType)
		if ok {
			return reply.ErrorReply("Key already exists")
		} else {
			raw_hash, _ := scrypt.Key([]byte(args[1]), []byte(args[0]), 16384, 8, 1, 32)
			b64_hash := store.Base64Encode(raw_hash)
			final_hash := fmt.Sprintf("$%d$%d$%d$%s", 16384, 8, 1, string(b64_hash))
			user := &User{args[0], final_hash, "", 0}
			db.StoreSet(args[0], &data.Entry{user, UserType})
			return reply.OKReply
		}
		return reply.OKReply
	})

	store.DefaultDBManager.AddFunc("userget", func(db *store.DB, args []string) string {
		s := args[0]
		e, ok, _ := db.StoreGet(s, UserType)
		if ok {
			if user, ok := e.Value.(*User); ok {
				score_str := fmt.Sprintf("%d", user.Score)
				var rep reply.MultiBulkWriter
				rep.WriteCount(2)
				rep.WriteString(user.Username)
				rep.WriteString(score_str)
				return rep.String()
			} else {
				return reply.ErrorReply("Type Mismatch")
			}
		} else {
			return reply.NilReply
		}
	})

	store.DefaultDBManager.AddFuncWithSideEffects("userauth", func(db *store.DB, args []string) string {
		username := args[0]
		e, ok, _ := db.StoreGet(username, UserType)
		if ok {
			if user, ok := e.Value.(*User); ok {
				password := args[1]
				raw_hash, _ := scrypt.Key([]byte(password), []byte(username), 16384, 8, 1, 32)
				b64_hash := store.Base64Encode(raw_hash)
				final_hash := fmt.Sprintf("$%d$%d$%d$%s", 16384, 8, 1, string(b64_hash))
				if final_hash == user.Hash {
					c := 64
					b := make([]byte, c)
					n, err := io.ReadFull(rand.Reader, b)
					if n != len(b) || err != nil {
						return reply.ErrorReply("Unable to generate a secure random token")
					}
					token := store.Base64Encode(b)
					token_str := string(token)
					db.StoreSet(token_str, &data.Entry{username, 0})
					if user.Token != "" {
						db.StoreDel(token_str)
					}
					user.Token = token_str
					return reply.BulkReply(token_str)
				} else {
					return reply.ErrorReply("Password is incorrect")
				}
			} else {
				return reply.ErrorReply("How did you manage to mess things up this good?")
			}
		} else {
			return reply.ErrorReply("No user exists with that username")
		}
	})

	store.DefaultDBManager.AddFunc("usertoken", func(db *store.DB, args []string) string {
		token := args[0]

		e, ok, _ := db.StoreGet(token, strings.StringType)
		if ok {
			str, _ := e.Value.(string)
			return reply.BulkReply(str)
		} else {
			return reply.ErrorReply("Invalid or expired token")
		}
	})

}
コード例 #5
0
ファイル: set.go プロジェクト: brianbrunner/omg
func init() {

	gob.Register(make(map[string]bool))

	store.RegisterStoreType(SetType)

	store.DefaultDBManager.AddFuncWithSideEffects("sadd", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)

		if err != nil {
			return reply.ErrorReply("Type Mismatch")
		}

		var setData map[string]bool
		if !ok {
			setData = make(map[string]bool)
			db.StoreSet(args[0], &data.Entry{setData, SetType})
		} else {
			setData, _ = e.Value.(map[string]bool)
		}

		l := len(args)
		sdata := args[1:l]
		count := 0
		for _, member := range sdata {
			_, ok = setData[member]
			if !ok {
				setData[member] = true
				count += 1
			}
		}
		return reply.IntReply(count)
	})

	store.DefaultDBManager.AddFuncWithSideEffects("srem", func(db *store.DB, args []string) string {

		e, ok, err := db.StoreGet(args[0], SetType)
		if err != nil {
			return reply.ErrorReply("Type Mismatch")
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if !ok {
			setData = make(map[string]bool)
			db.StoreSet(args[0], &data.Entry{setData, SetType})
		}

		l := len(args)
		sdata := args[1:l]
		count := 0
		for _, member := range sdata {
			_, ok = setData[member]
			if ok {
				delete(setData, member)
				count += 1
			}
		}

		return reply.IntReply(count)
	})

	store.DefaultDBManager.AddFuncWithSideEffects("srem", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)
		if err != nil {
			return reply.ErrorReply("Type Mismatch")
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if !ok {
			setData = make(map[string]bool)
		}
		l := len(args)
		sdata := args[1:l]
		count := 0
		for _, member := range sdata {
			_, ok = setData[member]
			if ok {
				delete(setData, member)
				count += 1
			}
		}
		return reply.IntReply(count)
	})

	store.DefaultDBManager.AddFunc("sismember", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)

		if err != nil || !ok {
			return "-ERR Type Mismatch\r\n"
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if !ok {
			return reply.IntReply(0)
		}
		_, ok = setData[args[1]]
		if ok {
			return reply.IntReply(1)
		}
		return reply.IntReply(0)
	})

	store.DefaultDBManager.AddFunc("scard", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)

		if err != nil || !ok {
			return reply.ErrorReply("Type Mismatch")
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if ok {
			return reply.IntReply(len(setData))
		}
		return reply.IntReply(0)
	})

	store.DefaultDBManager.AddFuncWithSideEffects("spop", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)

		if err != nil || !ok {
			return "-ERR Type Mismatch\r\n"
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if !ok {
			return reply.NilReply
		}
		for k, _ := range setData {
			delete(setData, k)
			return reply.BulkReply(k)
		}
		return reply.NilReply
	})

	store.DefaultDBManager.AddFuncWithSideEffects("smembers", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)

		if err != nil || !ok {
			return "-ERR Type Mismatch\r\n"
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if !ok {
			return reply.NilReply
		}

		var w reply.MultiBulkWriter
		w.WriteCount(len(setData))
		for k, _ := range setData {
			w.WriteString(k)
		}
		return w.String()
	})

	store.DefaultDBManager.AddFuncWithSideEffects("srandmember", func(db *store.DB, args []string) string {
		e, ok, err := db.StoreGet(args[0], SetType)

		if err != nil || !ok {
			return "-ERR Type Mismatch\r\n"
		}
		if !ok {
			return reply.NilReply
		}

		setData, ok := e.Value.(map[string]bool)
		if !ok {
			return reply.NilReply
		}

		if len(args) > 1 {

			count, err := strconv.Atoi(args[1])
			if err != nil {
				panic(err)
			}

			var w reply.MultiBulkWriter
			w.WriteCount(count)
			for k, _ := range setData {
				w.WriteString(k)
				count -= 1
				if count == 0 {
					break
				}
			}
			return w.String()

		} else {

			for k, _ := range setData {
				return reply.BulkReply(k)
			}

		}

		return reply.NilReply

	})

}
コード例 #6
0
ファイル: replication.go プロジェクト: brianbrunner/omg
func init() {

	slaveChan := make(chan string)

	var slaveConn net.Conn

	go func() {

		c := parser.CommandParser{}
		c.Reset()
		c.Restart()
		replyChan := make(chan string)
		line := make([]byte, 1024)
		var done bool
		var err error
		var commands []com.Command
		comChan := store.DefaultDBManager.ComChan

		for {

			master := <-slaveChan

			if slaveConn != nil {
				slaveConn.Close()
				slaveConn = nil
			}

			if master != "NO:ONE" {

				slaveConn, err = net.Dial("tcp", master)
				if err == nil {

					slaveConn.Write([]byte("*1\r\n$4\r\nSYNC\r\n"))

					go func() {

						db_dec := gob.NewDecoder(slaveConn)
						store.DefaultDBManager.LoadFromGobDecoder(db_dec)

						for {
							n, err := slaveConn.Read(line[:])
							if err != nil {
								return
							}

							done, commands, err = c.ParseBytes(line[:n])
							if err != nil {
								break
							}

							// if we've processed any commands, run them

							if done {

								for _, command := range commands {
									command.ReplyChan = replyChan
									comChan <- command
									<-replyChan
								}
								c.Reset()

							}

						}

					}()

				} else {
					slaveChan <- reply.ErrorReply(fmt.Sprintf("Unable to connect to server at %s", master))
					continue
				}
			}

			slaveChan <- reply.OKReply

		}

	}()

	store.DefaultDBManager.AddFunc("slaveof", func(db *store.DB, args []string) string {
		ip := args[0]
		port := args[1]
		slaveChan <- fmt.Sprintf("%s:%s", ip, port)
		return <-slaveChan
	})

	store.DefaultDBManager.AddFunc("movebucket", func(db *store.DB, args []string) string {
		ip := args[0]
		port := args[1]
		bucket, err := strconv.Atoi(args[2])
		if err != nil {
			return reply.ErrorReply("Invalid bucket")
		}
		slaveChan <- fmt.Sprintf("%s:%s", ip, port)
		return <-slaveChan
	})

}