package component import ( "bytes" "context" "fmt" "gitea.party/public-messag-service/config" "github.com/go-redis/redis/v8" "github.com/urfave/cli/v2" "net/url" "strconv" "strings" "time" ) type RedisClient struct { DB *redis.Client Cfg config.EntityRedis ref *Redis } func (c *RedisClient) Ref() *Redis { return c.ref } func (c *RedisClient) CliFlags(name string) []cli.Flag { return []cli.Flag{ &cli.IntFlag{ Name: fmt.Sprintf("redis-%s-open-limit", name), Usage: fmt.Sprintf("redis(%s) max open limit", name), Action: func(_ *cli.Context, v int) error { c.Cfg.PoolSize = v; return nil }, }, &cli.StringFlag{ Name: fmt.Sprintf("redis-%s-dsn", name), Usage: fmt.Sprintf("redis(%s) DSN (format: `user:{{password}}@{{ip}}:{{port}}/{{db}}`)", name), Action: func(_ *cli.Context, dsn string) error { pv, err := url.Parse("redis://" + dsn) if err == nil { c.Cfg.Addr = pv.Host c.Cfg.Pwd, _ = pv.User.Password() c.Cfg.DB, _ = strconv.Atoi(strings.Trim(pv.Path, "/")) } if err != nil { return fmt.Errorf("redis DSN is invalid(%s)[url parse faild err_msg:%s]", dsn, err.Error()) } return nil }, }, } } func (c *RedisClient) Init(env int, cc *Redis) { c.ref = cc } func (c *RedisClient) Config() *config.EntityRedis { return &c.Cfg } func (c *RedisClient) Load(name string) error { c.DB = redis.NewClient(&redis.Options{ Addr: c.Cfg.Addr, Password: c.Cfg.Pwd, DB: c.Cfg.DB, PoolSize: c.Cfg.PoolSize, MinIdleConns: c.Cfg.PoolSize/3 + 1, IdleTimeout: time.Second * time.Duration(c.ref.Cfg.IdleCheckTime), ReadTimeout: time.Second * time.Duration(c.ref.Cfg.MaxReadTime), WriteTimeout: time.Second * time.Duration(c.ref.Cfg.MaxWriteTime), }) if _, err := c.DB.Ping(context.Background()).Result(); err != nil { c.DB = nil return fmt.Errorf("Load Redis (%s) Failed (Ping-Error: %s) ", name, err.Error()) } return nil } func (c *RedisClient) ApiLog(args [][2]interface{}) func() { bTm := time.Now() return func() { spendTime := time.Now().Sub(bTm) / time.Millisecond var handler func(string, ...interface{}) //if spendTime > time.Duration(c.ref.Cfg.SlowThreshold) { // 查询超过阈值 // handler = c.ref.Log //} else if c.ref.Log.Level() == logger.Info { // handler = c.ref.Log.InfoForce //} if handler != nil { var format bytes.Buffer format.WriteString("Redis[%d ms]: ") fArgs := make([]interface{}, 0, 2+len(args)*2) fArgs = append(fArgs, spendTime) for i, l := 0, len(args); i < l; i++ { format.WriteString("\n\t%s: %+v") fArgs = append(fArgs, args[0][0], args[0][1]) } handler(format.String(), fArgs...) } } }