Ejemplo n.º 1
1
Archivo: commands.go Proyecto: mc0/okq
// Dispatch takes in a client whose command has already been read off the
// socket, a list of arguments from that command (not including the command name
// itself), and handles that command
func Dispatch(client *clients.Client, cmd string, args []string) {
	cmdInfo, ok := commandMap[strings.ToUpper(cmd)]
	if !ok {
		writeErrf(client.Conn, "ERR unknown command %q", cmd)
		return
	}

	if len(args) < cmdInfo.minArgs {
		writeErrf(client.Conn, "ERR missing args")
		return
	}

	ret, err := cmdInfo.f(client, args)
	if err != nil {
		writeErrf(client.Conn, "ERR unexpected server-side error")
		log.L.Print(client.Sprintf("command %s %#v err: %s", cmd, args, err))
		return
	}

	redis.NewResp(ret).WriteTo(client.Conn)
}
Ejemplo n.º 2
0
func TestSaveEvent(t *testing.T) {
	fake := FakeRedis{}
	db := DB{"", fake}

	fakeHLEN = redis.NewResp(22)
	fakeHSET = redis.NewResp(nil)

	buf := bytes.NewBufferString("test")
	if err := db.SaveEvent(1, buf); err != nil {
		t.Errorf("Should not have errored: %s", err.Error())
	}

	if len(capture) != 3 {
		t.Fatalf("Need 3 params to HSET, got %d", len(capture))
	}
	store, _ := capture[0].(string)
	if store != "ES:1" {
		t.Errorf("Should have saved to store ES:1, but got %s", store)
	}
	eid, _ := capture[1].(int)
	if eid != 22 {
		t.Errorf("Should have saved with event id 22, but got %d", eid)
	}
	if buf != capture[2] {
		t.Errorf("Should have used the provided buffer")
	}
}
Ejemplo n.º 3
0
func (d *clusterDB) Lua(cmd string, numKeys int, args ...interface{}) *redis.Resp {
	key, err := redis.KeyFromArgs(args)
	if err != nil {
		return redis.NewResp(err)
	}

	c, err := d.GetForKey(key)
	if err != nil {
		return redis.NewResp(err)
	}
	defer d.Put(c)

	return luaHelper(c, cmd, numKeys, args...)
}
Ejemplo n.º 4
0
func TestLoadStores(t *testing.T) {
	fake := FakeRedis{}
	db := DB{"", fake}

	fakeKEYS = redis.NewResp([]string{
		"ES:1", "ES:2", "ES:3",
	})

	stores, err := db.LoadStores()
	if err != nil {
		t.Fatalf("LoadStores should not have errored: %s", err.Error())
	}
	if len(stores) != 3 {
		t.Fatalf("Expected 3 stores but got %d", len(stores))
	}

	if stores[0] != "ES:1" {
		t.Errorf("Expected store 0 to be ES:1 but was %s", stores[0])
	}
	if stores[1] != "ES:2" {
		t.Errorf("Expected store 1 to be ES:2 but was %s", stores[1])
	}
	if stores[2] != "ES:3" {
		t.Errorf("Expected store 2 to be ES:3 but was %s", stores[2])
	}
}
Ejemplo n.º 5
0
Archivo: db_lua.go Proyecto: mc0/okq
func luaHelper(
	c *redis.Client, cmd string, numKeys int, args ...interface{},
) *redis.Resp {

	cmd = strings.ToUpper(cmd)
	l, ok := luaScripts[cmd]
	if !ok {
		return redis.NewResp(fmt.Errorf("unknown lua script: %s", cmd))
	}

	realArgs := make([]interface{}, 0, len(args)+2)
	realArgs = append(realArgs, l.hash, numKeys)
	realArgs = append(realArgs, args...)

	r, notLoaded := luaEvalSha(c, realArgs)
	if !notLoaded {
		return r
	}

	if err := c.Cmd("SCRIPT", "LOAD", l.script).Err; err != nil {
		return r
	}

	r, _ = luaEvalSha(c, realArgs)
	return r
}
Ejemplo n.º 6
0
func TestGetEvents(t *testing.T) {
	fake := FakeRedis{}
	db := DB{"", fake}

	fakeHGETALL = redis.NewResp([]string{
		"1", "test1", "0", "test2", "2", "test3",
	})
	bufs, err := db.GetEvents(1)
	if err != nil {
		t.Fatalf("Should not have errored getting events: %s", err.Error())
	}

	if len(bufs) != 3 {
		t.Fatalf("Expected 3 events but got %d", len(bufs))
	}
	zero := bufs[0].String()
	if zero != "test2" {
		t.Errorf("Expected event 0 to be test2 but got %s", zero)
	}
	one := bufs[1].String()
	if one != "test1" {
		t.Errorf("Expected event 1 to be test1 but got %s", one)
	}
	two := bufs[2].String()
	if two != "test3" {
		t.Errorf("Expected event 2 to be test3 but got %s", two)
	}
}
Ejemplo n.º 7
0
// Cmd automatically gets one client from the pool, executes the given command
// (returning its result), and puts the client back in the pool
func (p *Pool) Cmd(cmd string, args ...interface{}) *redis.Resp {
	c, err := p.Get()
	if err != nil {
		return redis.NewResp(err)
	}
	defer p.Put(c)

	return c.Cmd(cmd, args...)
}
Ejemplo n.º 8
0
func (d *sentinelDB) Cmd(cmd string, args ...interface{}) *redis.Resp {
	sentinel, conn, err := d.getSentinelAndMaster()
	if err != nil {
		return redis.NewResp(err)
	}
	defer sentinel.PutMaster(config.RedisSentinelGroup, conn)

	return conn.Cmd(cmd, args...)
}
Ejemplo n.º 9
0
func (d sentinelDB) Lua(cmd string, numKeys int, args ...interface{}) *redis.Resp {
	sentinel, c, err := d.getSentinelAndMaster()
	if err != nil {
		return redis.NewResp(err)
	}
	defer sentinel.PutMaster(config.RedisSentinelGroup, c)

	r := luaHelper(c, cmd, numKeys, args...)
	return r
}
Ejemplo n.º 10
0
Archivo: db_normal.go Proyecto: mc0/okq
func (d normalDB) Lua(cmd string, numKeys int, args ...interface{}) *redis.Resp {
	c, err := d.Get()
	if err != nil {
		return redis.NewResp(err)
	}

	r := luaHelper(c, cmd, numKeys, args...)
	d.Put(c)
	return r
}
Ejemplo n.º 11
0
Archivo: db_normal.go Proyecto: mc0/okq
func (d *normalDB) Cmd(cmd string, args ...interface{}) *redis.Resp {
	c, err := d.Get()
	if err != nil {
		return redis.NewResp(err)
	}

	r := c.Cmd(cmd, args...)
	d.Put(c)
	return r
}
Ejemplo n.º 12
0
func TestNextStoreID(t *testing.T) {
	fake := FakeRedis{}
	db := DB{"", fake}

	fakeINCR = redis.NewResp(11)
	sid, err := db.NextStoreID()
	if err != nil {
		t.Fatalf("Should not have errored during id increment: %s", err.Error())
	}
	if sid != 11 {
		t.Errorf("Expected next store id to be 11 but was %d", sid)
	}
}
Ejemplo n.º 13
0
func (rs *RedisStorage) Cmd(cmd string, args ...interface{}) *redis.Resp {
	c, err := rs.db.Get()
	if err != nil {
		return redis.NewResp(err)
	}
	result := c.Cmd(cmd, args...)
	if result.IsType(redis.IOErr) {
		rs.IncreasePool()
		utils.Logger.Warning(fmt.Sprintf("RedisClient error '%s'", result.String()))
		return rs.Cmd(cmd, args...)
	}
	rs.db.Put(c)
	return result
}
Ejemplo n.º 14
0
// LuaEval calls EVAL on the given Cmder for the given script, passing the key
// count and argument list in as well. See http://redis.io/commands/eval for
// more on how EVAL works and for the meaning of the keys argument.
//
// LuaEval will automatically try to call EVALSHA first in order to preserve
// bandwidth, and only falls back on EVAL if the script has never been used
// before.
//
// This method works with any of the Cmder's implemented in radix.v2, including
// Client, Pool, and Cluster.
//
//	r := util.LuaEval(c, `return redis.call('GET', KEYS[1])`, 1, "foo")
//
func LuaEval(c Cmder, script string, keys int, args ...interface{}) *redis.Resp {
	mainKey, _ := redis.KeyFromArgs(args...)

	sumRaw := sha1.Sum([]byte(script))
	sum := hex.EncodeToString(sumRaw[:])

	var r *redis.Resp
	if err := withClientForKey(c, mainKey, func(cc Cmder) {
		r = c.Cmd("EVALSHA", sum, keys, args)
		if r.Err != nil && strings.HasPrefix(r.Err.Error(), "NOSCRIPT") {
			r = c.Cmd("EVAL", script, keys, args)
		}
	}); err != nil {
		return redis.NewResp(err)
	}

	return r
}
Ejemplo n.º 15
0
// This CMD function get a connection from the pool.
// Handles automatic failover in case of network disconnects
func (rs *RedisStorage) Cmd(cmd string, args ...interface{}) *redis.Resp {
	c1, err := rs.dbPool.Get()
	if err != nil {
		return redis.NewResp(err)
	}
	result := c1.Cmd(cmd, args...)
	if result.IsType(redis.IOErr) { // Failover mecanism
		utils.Logger.Warning(fmt.Sprintf("<RedisStorage> error <%s>, attempting failover.", result.Err.Error()))
		for i := 0; i < rs.maxConns; i++ { // Two attempts, one on connection of original pool, one on new pool
			c2, err := rs.dbPool.Get()
			if err == nil {
				if result2 := c2.Cmd(cmd, args...); !result2.IsType(redis.IOErr) {
					rs.dbPool.Put(c2)
					return result2
				}
			}
		}
	} else {
		rs.dbPool.Put(c1)
	}
	return result
}
Ejemplo n.º 16
0
func TestPublishEvent(t *testing.T) {
	fake := FakeRedis{}
	db := DB{"", fake}

	fakePUBLISH = redis.NewResp(1)

	buf := bytes.NewBufferString("test")
	if err := db.PublishEvent("ename", buf); err != nil {
		t.Fatalf("Should not have errored: %s", err.Error())
	}

	if len(capture) != 2 {
		t.Fatalf("Need 2 params to PUBLISH, got %d", len(capture))
	}
	channel, _ := capture[0].(string)
	if channel != "ename" {
		t.Errorf("Should have published to ename but went to %s", channel)
	}
	if buf != capture[1] {
		t.Errorf("Should have used the provided buffer")
	}
}
Ejemplo n.º 17
0
func errorResp(err error) *redis.Resp {
	return redis.NewResp(err)
}
Ejemplo n.º 18
0
Archivo: server.go Proyecto: mc0/okq
		go serveClient(client)
	}
}

func acceptConns(listener net.Listener, incomingConns chan net.Conn) {
	for {
		conn, err := listener.Accept()
		if conn == nil {
			log.L.Printf("couldn't accept: %q", err)
			continue
		}
		incomingConns <- conn
	}
}

var invalidCmdResp = redis.NewResp(errors.New("ERR invalid command"))

func serveClient(client *clients.Client) {
	conn := client.Conn
	rr := redis.NewRespReader(conn)

outer:
	for {
		var command string
		var args []string

		m := rr.Read()
		if m.IsType(redis.IOErr) {
			log.L.Debug(client.Sprintf("client connection error %q", m.Err))
			if len(client.Queues) > 0 {
				consumers.UpdateQueues(client, []string{})
Ejemplo n.º 19
0
Archivo: commands.go Proyecto: mc0/okq
func writeErrf(w io.Writer, format string, args ...interface{}) {
	err := fmt.Errorf(format, args...)
	redis.NewResp(err).WriteTo(w)
}