| @ -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) | |||
| } | |||