123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package redis
- import (
- "fmt"
- "github.com/gomodule/redigo/redis"
- "github.com/spf13/viper"
- "strings"
- "time"
- )
- // redigo适配器
- type RedigoAdapter struct {
- pool *redis.Pool
- }
- // 返回redigo适配器新实例
- func NewRedigoAdapter(addr string) (IRedisAdapter, error) {
- opts := []redis.DialOption{redis.DialConnectTimeout(5 * time.Second)}
- password := viper.GetString("redis.password")
- if len(strings.TrimSpace(password)) > 0 {
- opts = append(opts, redis.DialPassword(strings.TrimSpace(password)))
- }
- pool, err := createPool(addr, opts...)
- if nil != err {
- return nil, err
- }
- return &RedigoAdapter{
- pool: pool,
- }, nil
- }
- // 创建redis连接池
- func createPool(addr string, opts ...redis.DialOption) (*redis.Pool, error) {
- maxIdle := viper.GetInt("redis.max_idle")
- maxActive := viper.GetInt("redis.max_active")
- idleTimeout := viper.GetDuration("redis.timeout")
- return &redis.Pool{
- MaxIdle: maxIdle,
- MaxActive: maxActive,
- IdleTimeout: idleTimeout,
- Dial: func() (redis.Conn, error) {
- if conn, err := redis.Dial("tcp", addr, opts...); nil != err {
- return nil, err
- } else {
- return conn, nil
- }
- },
- TestOnBorrow: func(c redis.Conn, t time.Time) error {
- _, err := c.Do("PING")
- return err
- },
- }, nil
- }
- // 关闭Redis连接
- func (a *RedigoAdapter) Close() error {
- return a.pool.Close()
- }
- // 执行Redis命令
- func (a *RedigoAdapter) Do(commandName string, args ...interface{}) (interface{}, error) {
- conn := a.pool.Get()
- defer func(conn redis.Conn) {
- _ = conn.Close()
- }(conn)
- if nil == conn {
- return nil, ErrRedisConnNil
- } else {
- return conn.Do(commandName, args...)
- }
- }
- // 返回命令管道操作对象
- func (a *RedigoAdapter) Pipeline() IRedisPipeline {
- return &RedigoPipeline{
- conn: a.pool.Get(),
- }
- }
- // Redigo命令管道操作对象
- type RedigoPipeline struct {
- conn redis.Conn
- commands []*redisCmd
- }
- // 向管道中添加命令
- func (p *RedigoPipeline) Send(commandName string, args ...interface{}) IRedisPipeline {
- p.commands = append(p.commands, &redisCmd{commandName: commandName, args: args})
- return p
- }
- // 执行管道中的命令
- func (p *RedigoPipeline) Execute() ([]interface{}, error) {
- defer func(conn redis.Conn) {
- _ = conn.Close()
- }(p.conn)
- if nil == p.commands || len(p.commands) == 0 {
- return nil, fmt.Errorf("no commands in pipeline")
- }
- var err error
- for i := 0; i < len(p.commands); i++ {
- cmd := p.commands[i]
- err = p.conn.Send(cmd.commandName, cmd.args...)
- if nil != err {
- return nil, err
- }
- }
- err = p.conn.Flush()
- if nil != err {
- return nil, err
- }
- var replies []interface{}
- for i := 0; i < len(p.commands); i++ {
- reply, err := p.conn.Receive()
- if nil != err {
- return nil, err
- }
- replies = append(replies, reply)
- }
- return replies, nil
- }
|