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