110 lines
2.4 KiB
Go
110 lines
2.4 KiB
Go
|
|
package util
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"fmt"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/redis/go-redis/v9"
|
||
|
|
)
|
||
|
|
|
||
|
|
// RedisOptions define struct of redis client config options
|
||
|
|
type RedisOptions struct {
|
||
|
|
Addr string
|
||
|
|
Password string
|
||
|
|
DB int
|
||
|
|
PoolSize int
|
||
|
|
Timeout time.Duration
|
||
|
|
}
|
||
|
|
|
||
|
|
// RedisOption define a function type for modify RedisOptions
|
||
|
|
type RedisOption func(*RedisOptions) error
|
||
|
|
|
||
|
|
// WithAddr define func of configure redis addr options
|
||
|
|
func WithAddr(addr string) RedisOption {
|
||
|
|
return func(o *RedisOptions) error {
|
||
|
|
if addr == "" {
|
||
|
|
return errors.New("地址不能为空")
|
||
|
|
}
|
||
|
|
o.Addr = addr
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// WithPassword define func of configure redis password options
|
||
|
|
func WithPassword(password string) RedisOption {
|
||
|
|
return func(o *RedisOptions) error {
|
||
|
|
o.Password = password
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// WithDB define func of configure redis db options
|
||
|
|
func WithDB(db int) RedisOption {
|
||
|
|
return func(o *RedisOptions) error {
|
||
|
|
if db < 0 {
|
||
|
|
return errors.New("数据库编号不能为负数")
|
||
|
|
}
|
||
|
|
o.DB = db
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// WithPoolSize define func of configure pool size options
|
||
|
|
func WithPoolSize(poolSize int) RedisOption {
|
||
|
|
return func(o *RedisOptions) error {
|
||
|
|
if poolSize <= 0 {
|
||
|
|
return errors.New("连接池大小必须大于 0")
|
||
|
|
}
|
||
|
|
o.PoolSize = poolSize
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// WithTimeout define func of configure timeout options
|
||
|
|
func WithTimeout(timeout time.Duration) RedisOption {
|
||
|
|
return func(o *RedisOptions) error {
|
||
|
|
if timeout <= 0 {
|
||
|
|
return errors.New("超时时间必须大于 0")
|
||
|
|
}
|
||
|
|
o.Timeout = timeout
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewRedisClient define func of initialize the Redis client
|
||
|
|
func NewRedisClient(opts ...RedisOption) (*redis.Client, error) {
|
||
|
|
// default options
|
||
|
|
options := &RedisOptions{
|
||
|
|
Addr: "localhost:6379",
|
||
|
|
Password: "",
|
||
|
|
DB: 0,
|
||
|
|
PoolSize: 10,
|
||
|
|
Timeout: 5 * time.Second,
|
||
|
|
}
|
||
|
|
|
||
|
|
// Apply configuration options from config
|
||
|
|
for _, opt := range opts {
|
||
|
|
if err := opt(options); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// create redis client
|
||
|
|
client := redis.NewClient(&redis.Options{
|
||
|
|
Addr: options.Addr,
|
||
|
|
Password: options.Password,
|
||
|
|
DB: options.DB,
|
||
|
|
PoolSize: options.PoolSize,
|
||
|
|
})
|
||
|
|
|
||
|
|
// check if the connection is successful
|
||
|
|
ctx, cancel := context.WithTimeout(context.Background(), options.Timeout)
|
||
|
|
defer cancel()
|
||
|
|
if err := client.Ping(ctx).Err(); err != nil {
|
||
|
|
return nil, fmt.Errorf("can not connect redis:%v", err)
|
||
|
|
}
|
||
|
|
return client, nil
|
||
|
|
}
|