@ -0,0 +1,5 @@ | |||||
module git.tetele.net/tgo/redis | |||||
go 1.14 | |||||
require github.com/gomodule/redigo v2.0.0+incompatible // indirect |
@ -0,0 +1,3 @@ | |||||
github.com/gomodule/redigo v1.7.0 h1:ZKld1VOtsGhAe37E7wMxEDgAlGM5dvFY+DiOhSkhP9Y= | |||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= | |||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= |
@ -0,0 +1,17 @@ | |||||
package redis | |||||
func Incr(key string) (interface{}, error) { | |||||
c := pool.Get() | |||||
defer c.Close() | |||||
return c.Do("INCR", key) | |||||
} | |||||
func Decr(key string) (interface{}, error) { | |||||
c := pool.Get() | |||||
defer c.Close() | |||||
return c.Do("DECR", key) | |||||
} |
@ -0,0 +1,13 @@ | |||||
package redis | |||||
import ( | |||||
"testing" | |||||
) | |||||
func Test_Incr(t *testing.T) { | |||||
reply, err := Incr("xxx") | |||||
t.Log(reply, err) | |||||
reply, err := Decr("xxx") | |||||
t.Log(reply, err) | |||||
} |
@ -0,0 +1,72 @@ | |||||
package redis | |||||
import ( | |||||
"errors" | |||||
"time" | |||||
redisdb "github.com/gomodule/redigo/redis" | |||||
) | |||||
type Tx struct { | |||||
conn redisdb.Conn | |||||
} | |||||
func NewTx() (*Tx, error) { | |||||
var conn redisdb.Conn | |||||
var i int = 0 | |||||
var err error | |||||
for { | |||||
if i > 100 { | |||||
break | |||||
} | |||||
conn = pool.Get() | |||||
if conn != nil { | |||||
break | |||||
} else { | |||||
err = errors.New("no conn") | |||||
} | |||||
i++ | |||||
time.Sleep(time.Microsecond * 1000) | |||||
} | |||||
if conn != nil { | |||||
n := &Tx{conn: pool.Get()} | |||||
return n, nil | |||||
} else { | |||||
return nil, err | |||||
} | |||||
} | |||||
func (tx *Tx) GetInt(key string) (int, error) { | |||||
return redisdb.Int(tx.conn.Do("GET", key)) | |||||
} | |||||
func (tx *Tx) Watch(key string) (interface{}, error) { | |||||
return tx.conn.Do("WATCH", key) | |||||
} | |||||
func (tx *Tx) Multi() (interface{}, error) { | |||||
return tx.conn.Do("MULTI") | |||||
} | |||||
func (tx *Tx) Exec() (interface{}, error) { | |||||
return tx.conn.Do("Exec") | |||||
} | |||||
func (tx *Tx) Incr(key string) (interface{}, error) { | |||||
return tx.conn.Do("INCR", key) | |||||
} | |||||
func (tx *Tx) Decr(key string) (interface{}, error) { | |||||
return tx.conn.Do("DECR", key) | |||||
} | |||||
func (tx *Tx) Close() error { | |||||
return tx.conn.Close() | |||||
} |
@ -0,0 +1,71 @@ | |||||
package redis | |||||
import ( | |||||
"strconv" | |||||
"testing" | |||||
// "time" | |||||
) | |||||
var succ []int | |||||
func Test_Watch(t *testing.T) { | |||||
var key string = "tttttt" | |||||
// var tx *Tx | |||||
var count int | |||||
for i := 0; i < 100000; i++ { | |||||
// t.Log(i) | |||||
go func(i int) { | |||||
// t.Log(i) | |||||
tx, err := NewTx() | |||||
// t.Log(tx, err) | |||||
if err == nil { | |||||
reply, err := tx.Watch(key) | |||||
// t.Log("watch:", reply, err) | |||||
count_str, err := Get(key) | |||||
count, _ = strconv.Atoi(count_str) | |||||
// t.Log("count:", count, err) | |||||
reply, err = tx.Multi() | |||||
// t.Log("Multi:", reply, err) | |||||
if count > 0 && err == nil { | |||||
// t.Log("start decr,", i) | |||||
reply, err = tx.Decr(key) | |||||
// t.Log("Decr:", reply, err) | |||||
reply, err = tx.Exec() | |||||
// t.Log("Exec:", exec_reply, err, i) | |||||
if err == nil && reply != nil { | |||||
// reply, err = HSet("succ", i, i) | |||||
succ = append(succ, i) | |||||
t.Log("succ:", i, succ) | |||||
} | |||||
} | |||||
err = tx.Close() | |||||
// t.Log("Close:", err) | |||||
} | |||||
}(i) | |||||
} | |||||
t.Log(succ) | |||||
} |