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