// benchmark benchmarks the given function. func benchmark(data string, handle func(string, *redis.Client, chan struct{})) time.Duration { conf := redis.DefaultConfig() conf.Database = 8 conf.PoolCapacity = *connections c := redis.NewClient(conf) defer c.Close() rep := c.Flushdb() if rep.Err != nil { handleReplyError(rep) os.Exit(1) } ch := make(chan struct{}) start := time.Now() for i := 0; i < *connections; i++ { go handle(data, c, ch) } for i := 0; i < *requests; i++ { ch <- struct{}{} } dur := time.Now().Sub(start) return dur }
// TODO support domain sockets func redisConf() redis.Config { u := redisUrl() conf := redis.DefaultConfig() conf.Network = "tcp" conf.Address = u.Host if u.User != nil { pass, set := u.User.Password() if set { conf.Password = pass } } return conf }
func main() { var c *redis.Client conf := redis.DefaultConfig() // Network and address // // Default are "tcp" and "127.0.0.1:6379" so these are commented out. // TCP example: // conf.Network = "tcp" // conf.Address = "127.0.0.1:6379" // Unix example: // conf.Network = "unix" // conf.Address = "/tmp/redis.sock" conf.Database = 8 // Database number conf.Timeout = time.Duration(10) * time.Second // Socket timeout c = redis.NewClient(conf) defer c.Close() //** Blocking calls rep := c.Flushdb() if rep.Err != nil { fmt.Println("redis:", rep.Err) return } //* Strings // It's generally good idea to check for errors like this, // but for the sake of keeping this example short we'll omit these from now on. if rep = c.Set("mykey0", "myval0"); rep.Err != nil { fmt.Println("redis:", rep.Err) return } var err error var s string if rep = c.Get("mykey0_may_not_exist"); rep.Type == redis.ReplyNil { //key not found fmt.Println("key not found ") } else if s, err = rep.Str(); err != nil { fmt.Println("Get error ", err) return } fmt.Println("mykey0:", s) myhash := map[string]string{ "mykey1": "myval1", "mykey2": "myval2", "mykey3": "myval3", } // Alternatively: // c.Mset("mykey1", "myval1", "mykey2", "myval2", "mykey3", "myval3") c.Mset(myhash) ls, err := c.Mget("mykey1", "mykey2", "mykey3").List() if err != nil { fmt.Println(err) return } fmt.Println("mykeys values:", ls) //* List handling mylist := []string{"foo", "bar", "qux"} // Alternativaly: // c.Rpush("mylist", "foo", "bar", "qux") c.Rpush("mylist", mylist) mylist, err = c.Lrange("mylist_may_not_exist", 0, -1).List() if err != nil { fmt.Println(err) return } fmt.Println("mylist:", mylist) //* Hash handling // Alternatively: // c.Hmset("myhash", ""mykey1", "myval1", "mykey2", "myval2", "mykey3", "myval3") c.Hmset("myhash", myhash) myhash, err = c.Hgetall("myhash").Hash() if err != nil { fmt.Println(err) return } fmt.Println("myhash:", myhash) //* Multicalls rep = c.MultiCall(func(mc *redis.MultiCall) { mc.Set("multikey", "multival") mc.Get("multikey") }) // Multicall reply is guaranteed to have the same number of sub-replies as calls, // if it succeeds. They can be accessed through Reply.Elems. if rep.Err != nil { fmt.Println(rep.Err) return } s, err = rep.Elems[1].Str() if err != nil { fmt.Println(err) return } fmt.Println("multikey:", s) //* Transactions rep = c.Transaction(func(mc *redis.MultiCall) { mc.Set("trankey", "tranval") mc.Get("trankey") }) if rep.Err != nil { fmt.Println(rep.Err) return } s, err = rep.Elems[1].Str() if err != nil { fmt.Println(err) return } fmt.Println("trankey:", s) //* Complex transactions // Atomic INCR replacement with transactions myIncr := func(key string) *redis.Reply { return c.MultiCall(func(mc *redis.MultiCall) { var curval int mc.Watch(key) mc.Get(key) rep := mc.Flush() if rep.Err != nil { return } s, err := rep.Elems[1].Str() if err == nil { curval, err = strconv.Atoi(s) } nextval := curval + 1 mc.Multi() mc.Set(key, nextval) mc.Exec() }) } myIncr("ctrankey") myIncr("ctrankey") myIncr("ctrankey") s, err = c.Get("ctrankey").Str() if err != nil { fmt.Println(err) return } fmt.Println("ctrankey:", s) //** Asynchronous calls c.Set("asynckey", "asyncval") fut := c.AsyncGet("asynckey") // do something here // block until reply is available s, err = fut.Reply().Str() if err != nil { fmt.Println(err) return } fmt.Println("asynckey:", s) //* Pub/sub msgHdlr := func(msg *redis.Message) { switch msg.Type { case redis.MessageMessage: fmt.Printf("Received message \"%s\" from channel \"%s\".\n", msg.Payload, msg.Channel) case redis.MessagePmessage: fmt.Printf("Received pattern message \"%s\" from channel \"%s\" with pattern "+ "\"%s\".\n", msg.Payload, msg.Channel, msg.Pattern) default: fmt.Println("Received other message:", msg) } } sub, err_ := c.Subscription(msgHdlr) if err_ != nil { fmt.Printf("Failed to subscribe: '%s'!\n", err_) return } defer sub.Close() sub.Subscribe("chan1", "chan2") sub.Psubscribe("chan*") c.Publish("chan1", "foo") sub.Unsubscribe("chan1") c.Publish("chan2", "bar") // give some time for the message handler to receive the messages time.Sleep(time.Second) }
"flag" "fmt" "github.com/fzzbt/radix/redis" "os" "runtime" "runtime/pprof" "time" ) var connections *int = flag.Int("c", 50, "number of connections") var requests *int = flag.Int("n", 10000, "number of request") var dsize *int = flag.Int("d", 3, "data size") var cpuprof *string = flag.String("cpuprof", "", "filename for cpuprof") var gomaxprocs *int = flag.Int("p", 8, "GOMAXPROCS value") var database *int = flag.Int("b", 8, "database used for testing (WILL BE FLUSHED!)") var conf redis.Config = redis.DefaultConfig() func flushdb() *redis.Error { c := redis.NewClient(conf) defer c.Close() rep := c.Flushdb() return rep.Err } func test(c *redis.Client, ch chan struct{}, doneChan chan struct{}, command string, params ...interface{}) { for _ = range ch { r := c.Call(command, params...) if r.Err != nil { fmt.Println(r.Err) os.Exit(1) }
func main() { // initialize conf := redis.DefaultConfig() client := redis.NewClient(conf) fmt.Println(conf) fmt.Println(client) // set & get setRep := client.Set("foo", "bar") if setRep.Err != nil { panic(setRep.Err) } fmt.Println(setRep) getRep := client.Get("foo") if getRep.Err != nil { panic(getRep.Err) } getStr, _ := getRep.Str() fmt.Println(getRep) fmt.Println(getStr) // variadic calls client.Set("foo1", "bar1") client.Set("foo2", "bar2") client.Set("foo3", "bar3") mgetRep := client.Mget("foo1", "foo2", "foo3") fmt.Println(mgetRep) // multi calls mcRep := client.MultiCall(func(mc *redis.MultiCall) { mc.Set("k1", "v1") mc.Get("k1") }) if mcRep.Err != nil { panic(mcRep.Err) } mcVal, _ := mcRep.Elems[1].Str() fmt.Println(mcVal) // transactional calls tRep := client.Transaction(func(mc *redis.MultiCall) { mc.Set("k2", "v2") mc.Get("k2") }) if tRep.Err != nil { panic(tRep.Err) } tStr, _ := tRep.Elems[1].Str() fmt.Println(tStr) // pubsub msgHdlr := func(msg *redis.Message) { fmt.Println(msg) } sub, subErr := client.Subscription(msgHdlr) if subErr != nil { panic(subErr) } defer sub.Close() sub.Subscribe("chan1", "chan2") sub.Psubscribe("chan*") client.Publish("chan1", "foo") sub.Unsubscribe("chan1") client.Publish("chan2", "bar") time.Sleep(time.Second) }