This commit is contained in:
史悦
2025-08-13 19:03:20 +08:00
commit d62a2e9ed9
73 changed files with 7296 additions and 0 deletions

8
internal/cache/cacheable.go vendored Normal file
View File

@@ -0,0 +1,8 @@
package cache
type Cacheable interface {
Set(key string, value interface{}, ttl int) error
Get(key string) (interface{}, error)
Exist(key string) (bool, error)
Del(key string) error
}

100
internal/cache/memory.go vendored Normal file
View File

@@ -0,0 +1,100 @@
package cache
import (
"fmt"
"sync"
"time"
)
// MemoryMap 用于内存缓存
type MemoryMap struct {
cache map[string]interface{}
expirations map[string]int64
mu sync.Mutex
}
func NewMemoryMap() *MemoryMap {
m := &MemoryMap{}
m.init()
return m
}
// init 初始化 MemoryMap 的缓存
func (m *MemoryMap) init() {
m.cache = make(map[string]interface{})
m.expirations = make(map[string]int64)
}
func (m *MemoryMap) Get(key string) (interface{}, error) {
m.mu.Lock()
defer m.mu.Unlock()
expiration, exists := m.expirations[key]
currentTime := time.Now().UnixMilli()
if exists && currentTime > expiration {
// 键已过期,删除并返回 nil
fmt.Printf("Get: key=%s has expired, deleting...\n", key)
delete(m.cache, key)
delete(m.expirations, key)
return nil, nil
}
value, ok := m.cache[key]
if !ok {
return nil, nil
}
return value, nil
}
// Set 设置缓存中的值,并指定过期时间(秒)
func (m *MemoryMap) Set(key string, value interface{}, ttl int) error {
m.mu.Lock()
defer m.mu.Unlock()
m.cache[key] = value
if ttl == 0 {
// 默认半小时
ttl = 30 * 60
}
if ttl == -1 {
// -1 表示永久缓存,不设置过期时间
delete(m.expirations, key)
} else {
expiration := time.Now().UnixMilli() + int64(ttl*1000)
m.expirations[key] = expiration
}
return nil
}
func (m *MemoryMap) Exist(key string) (bool, error) {
m.mu.Lock()
defer m.mu.Unlock()
expiration, exists := m.expirations[key]
currentTime := time.Now().UnixMilli()
if exists && currentTime > expiration {
// 键已过期,删除并返回 nil
fmt.Printf("Get: key=%s has expired, deleting...\n", key)
delete(m.cache, key)
delete(m.expirations, key)
}
_, ok := m.cache[key]
return ok, nil
}
func (m *MemoryMap) Del(key string) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, ok := m.cache[key]; !ok {
return nil
}
delete(m.cache, key)
delete(m.expirations, key)
return nil
}
// 编译时检查
var _ Cacheable = (*MemoryMap)(nil)

25
internal/cache/operation.go vendored Normal file
View File

@@ -0,0 +1,25 @@
package cache
var cache Cacheable
func init() {
cache = NewMemoryMap()
// 已废弃redis缓存实现
/*host := os.Getenv("REDIS_HOST")
port := os.Getenv("REDIS_PORT")
psw := os.Getenv("REDIS_PASSWORD")
cache = NewRedisInstance(host, port, psw)*/
}
func Set(key string, value interface{}, ttl int) error {
return cache.Set(key, value, ttl)
}
func Get(key string) (interface{}, error) {
return cache.Get(key)
}
func Exist(key string) (bool, error) {
return cache.Exist(key)
}
func Del(key string) error {
return cache.Del(key)
}

82
internal/cache/redis.go vendored Normal file
View File

@@ -0,0 +1,82 @@
package cache
import (
"fmt"
"github.com/gomodule/redigo/redis"
"strconv"
"time"
)
type Redis struct {
Host string
Port string
Psw string
Pool *redis.Pool
}
func NewRedisInstance(host string, port string, psw string) *Redis {
r := &Redis{Host: host, Port: port, Psw: psw}
r.init()
return r
}
func (r *Redis) Get(k string) (interface{}, error) {
return r.getConn().Do("get", k)
}
func (r *Redis) Set(k string, v interface{}, ttl int) error {
_, err := r.getConn().Do("set", k, v, "EX", ttl)
return err
}
func (r *Redis) Exist(k string) (bool, error) {
return redis.Bool(r.getConn().Do("EXISTS", k))
}
func (r *Redis) Del(k string) error {
_, err := r.getConn().Do("del", k)
return err
}
func (r *Redis) getConn() redis.Conn {
return r.Pool.Get()
}
func (r *Redis) init() {
r.Pool = &redis.Pool{
// Maximum number of connections allocated by the pool at a given time.
// When zero, there is no limit on the number of connections in the pool.
//最大活跃连接数0代表无限
MaxActive: 1000,
//最大闲置连接数
// Maximum number of idle connections in the pool.
MaxIdle: 50,
//闲置连接的超时时间
// Close connections after remaining idle for this duration. If the value
// is zero, then idle connections are not closed. Applications should set
// the timeout to a value less than the server's timeout.
IdleTimeout: time.Second * 100,
//定义拨号获得连接的函数
// Dial is an application supplied function for creating and configuring a
// connection.
//
// The connection returned from Dial must not be in a special state
// (subscribed to pubsub channel, transaction started, ...).
Dial: func() (redis.Conn, error) {
port, _ := strconv.Atoi(r.Port)
c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", r.Host, port))
if err != nil {
return nil, err
}
password := r.Psw
if password != "" {
if _, err := c.Do("AUTH", password); err != nil {
c.Close()
return nil, err
}
}
return c, err
},
}
}