From 4610c020c300e7e78364cec000d0d503731cc686 Mon Sep 17 00:00:00 2001 From: Be <734742875@qq.com> Date: Sun, 15 Sep 2024 01:38:10 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=86=85=E5=AD=98=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/github_auth/code.go | 33 +++---- internal/cache/cacheable.go | 8 ++ internal/cache/memory.go | 100 +++++++++++++++++++++ internal/cache/operation.go | 36 ++++++++ internal/{redis/init.go => cache/redis.go} | 48 ++++++++-- internal/redis/operation.go | 42 --------- main.go | 4 - 7 files changed, 198 insertions(+), 73 deletions(-) create mode 100644 internal/cache/cacheable.go create mode 100644 internal/cache/memory.go create mode 100644 internal/cache/operation.go rename internal/{redis/init.go => cache/redis.go} (57%) delete mode 100644 internal/redis/operation.go diff --git a/internal/app/github_auth/code.go b/internal/app/github_auth/code.go index df380b5..3dc08cd 100644 --- a/internal/app/github_auth/code.go +++ b/internal/app/github_auth/code.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/gofrs/uuid" "github.com/gomodule/redigo/redis" - redisPkg "ripper/internal/redis" + "ripper/internal/cache" "strings" ) @@ -21,7 +21,6 @@ type ClientAuthInfo struct { // exp 过期时间 // return 用户代码, 设备代码, 错误 func BindClientToCode(clientId string, exp int) (string, string, error) { - rc := redisPkg.GetCoon() genCode := func() string { newUUID, _ := uuid.NewV4() uuidStr := strings.Replace(newUUID.String(), "-", "", -1) @@ -30,14 +29,14 @@ func BindClientToCode(clientId string, exp int) (string, string, error) { formattedUUID := genCode() rep := 0 redisKey := fmt.Sprintf("copilot.proxy.%s", formattedUUID) - repeat, _ := redis.Bool(rc.Do("EXISTS", redisKey)) + repeat, _ := cache.Exist(redisKey) for repeat { if rep > 5 { return "", "", fmt.Errorf("gen code error") } formattedUUID = genCode() redisKey = fmt.Sprintf("copilot.proxy.%s", formattedUUID) - repeat, _ = redis.Bool(rc.Do("EXISTS", redisKey)) + repeat, _ = cache.Exist(redisKey) rep++ } devId := GenDevicesCode(40) @@ -47,25 +46,24 @@ func BindClientToCode(clientId string, exp int) (string, string, error) { UserCode: formattedUUID, } authInfoData, _ := json.Marshal(authInfo) - _, err := rc.Do("set", redisKey, authInfoData, "EX", exp) + err := cache.Set(redisKey, authInfoData, exp) if err != nil { return "", "", err } redisKey = fmt.Sprintf("copilot.proxy.map.%s", devId) - _, err = rc.Do("set", redisKey, formattedUUID, "EX", exp) + err = cache.Set(redisKey, formattedUUID, exp) return formattedUUID, devId, err } // GetClientAuthInfoByDeviceCode 通过设备代码获取客户端授权信息 func GetClientAuthInfoByDeviceCode(deviceCode string) (*ClientAuthInfo, error) { - rc := redisPkg.GetCoon() redisKey := fmt.Sprintf("copilot.proxy.map.%s", deviceCode) - userCode, err := rc.Do("get", redisKey) + userCode, err := cache.Get(redisKey) if err != nil { return nil, err } redisKey = fmt.Sprintf("copilot.proxy.%s", userCode) - authInfoData, err := redis.Bytes(rc.Do("get", redisKey)) + authInfoData, err := redis.Bytes(cache.Get(redisKey)) if err != nil { return nil, err } @@ -75,9 +73,8 @@ func GetClientAuthInfoByDeviceCode(deviceCode string) (*ClientAuthInfo, error) { } func GetClientAuthInfo(code string) (ClientAuthInfo, error) { - rc := redisPkg.GetCoon() redisKey := fmt.Sprintf("copilot.proxy.%s", code) - authInfoData, err := redis.Bytes(rc.Do("get", redisKey)) + authInfoData, err := redis.Bytes(cache.Get(redisKey)) if err != nil { return ClientAuthInfo{}, err } @@ -98,14 +95,13 @@ func GenDevicesCode(codeLen int) string { // UpdateClientAuthStatusByDeviceCode 更新客户端授权码通过设备代码 func UpdateClientAuthStatusByDeviceCode(deviceCode string, cardCode string) error { - rc := redisPkg.GetCoon() redisKey := fmt.Sprintf("copilot.proxy.map.%s", deviceCode) - uCode, err := rc.Do("get", redisKey) + uCode, err := cache.Get(redisKey) if err != nil { return err } redisKey = fmt.Sprintf("copilot.proxy.%s", uCode) - authInfoData, err := redis.Bytes(rc.Do("get", redisKey)) + authInfoData, err := redis.Bytes(cache.Get(redisKey)) if err != nil { return err } @@ -116,23 +112,22 @@ func UpdateClientAuthStatusByDeviceCode(deviceCode string, cardCode string) erro } authInfo.CardCode = cardCode authInfoData, _ = json.Marshal(authInfo) - _, err = rc.Do("set", redisKey, authInfoData) + err = cache.Set(redisKey, authInfoData, -1) return err } func RemoveClientAuthInfoByDeviceCode(deviceCode string) error { - rc := redisPkg.GetCoon() redisKey := fmt.Sprintf("copilot.proxy.map.%s", deviceCode) - uCode, err := rc.Do("get", redisKey) + uCode, err := cache.Get(redisKey) if err != nil { return err } redisKey = fmt.Sprintf("copilot.proxy.%s", uCode) - _, err = rc.Do("del", redisKey) + err = cache.Del(redisKey) if err != nil { return err } redisKey = fmt.Sprintf("copilot.proxy.map.%s", deviceCode) - _, err = rc.Do("del", redisKey) + err = cache.Del(redisKey) return err } diff --git a/internal/cache/cacheable.go b/internal/cache/cacheable.go new file mode 100644 index 0000000..f839302 --- /dev/null +++ b/internal/cache/cacheable.go @@ -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 +} diff --git a/internal/cache/memory.go b/internal/cache/memory.go new file mode 100644 index 0000000..f721e4d --- /dev/null +++ b/internal/cache/memory.go @@ -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) diff --git a/internal/cache/operation.go b/internal/cache/operation.go new file mode 100644 index 0000000..e102369 --- /dev/null +++ b/internal/cache/operation.go @@ -0,0 +1,36 @@ +package cache + +import ( + "os" +) + +var cache Cacheable + +func init() { + cacheImp := "memory" + + switch cacheImp { + case "redis": + host := os.Getenv("REDIS_HOST") + port := os.Getenv("REDIS_PORT") + psw := os.Getenv("REDIS_PASSWORD") + instance := NewRedisInstance(host, port, psw) + cache = instance + case "memory": + cache = NewMemoryMap() + default: + cache = NewMemoryMap() + } +} +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) +} diff --git a/internal/redis/init.go b/internal/cache/redis.go similarity index 57% rename from internal/redis/init.go rename to internal/cache/redis.go index 39dcd36..b485469 100644 --- a/internal/redis/init.go +++ b/internal/cache/redis.go @@ -1,17 +1,49 @@ -package redis +package cache import ( "fmt" "github.com/gomodule/redigo/redis" - "os" "strconv" "time" ) -var pool *redis.Pool +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 InitRedis() { - pool = &redis.Pool{ +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代表无限 @@ -31,12 +63,12 @@ func InitRedis() { // 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(os.Getenv("REDIS_PORT")) - c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", os.Getenv("REDIS_HOST"), port)) + port, _ := strconv.Atoi(r.Port) + c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", r.Host, port)) if err != nil { return nil, err } - password := os.Getenv("REDIS_PASSWORD") + password := r.Psw if password != "" { if _, err := c.Do("AUTH", password); err != nil { c.Close() diff --git a/internal/redis/operation.go b/internal/redis/operation.go deleted file mode 100644 index ceefb19..0000000 --- a/internal/redis/operation.go +++ /dev/null @@ -1,42 +0,0 @@ -package redis - -import ( - "fmt" - "github.com/gomodule/redigo/redis" -) - -func GetCoon() redis.Conn { - return pool.Get() -} - -func GetOneString(key string) (string, error) { - redisconn := pool.Get() - defer redisconn.Close() - return redis.String(redisconn.Do("get", key)) -} - -func GetTokenVersion(db, key string) (int64, error) { - redisconn := pool.Get() - defer redisconn.Close() - return redis.Int64(redisconn.Do("get", fmt.Sprintf("Hzer:JWT:Version:%s:%s", db, key))) -} - -func SetTokenVersion(db, key string, value, expire int64, cover bool) (err error) { - redisconn := pool.Get() - defer redisconn.Close() - keys := fmt.Sprintf("Hzer:JWT:Version:%s:%s", db, key) - if !cover { - var exi bool - if exi, err = redis.Bool(redisconn.Do("EXISTS", keys)); err != nil { - return err - } - if exi { - return nil - } - } - if _, err = redisconn.Do("set", keys, value); err != nil { - return - } - _, err = redisconn.Do("expire", keys, expire) - return -} diff --git a/main.go b/main.go index 2aaf818..04afc52 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,6 @@ import ( "github.com/joho/godotenv" "log" "os" - "ripper/internal/redis" "ripper/internal/router" "strconv" ) @@ -23,9 +22,6 @@ func main() { //初始化router router.NewHTTPRouter(r) - // 初始化redis - redis.InitRedis() - //开启服务器 port, _ := strconv.Atoi(os.Getenv("PORT")) ipAddr := fmt.Sprintf("%s:%d", os.Getenv("HOST"), port) -- Gitee From 56899a78e560e69f530f2fea69e49b73adff0119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E8=B1=A1=E5=A5=94?= Date: Mon, 16 Sep 2024 00:37:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=A7=BB=E9=99=A4Redis=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 6 ------ docker-compose.yml | 11 ----------- internal/cache/operation.go | 23 ++++++----------------- 3 files changed, 6 insertions(+), 34 deletions(-) diff --git a/.env.example b/.env.example index 27c1741..c5ec7e4 100644 --- a/.env.example +++ b/.env.example @@ -26,9 +26,3 @@ API_BASE_URL=https://api.mycopilot.com ORIGIN_TRACKER_BASE_URL=https://origin-tracker.githubusercontent.com PROXY_BASE_URL=https://copilot-proxy.mycopilot.com TELEMETRY_BASE_URL=https://copilot-telemetry-service.mycopilot.com - -# redis配置 -REDIS_HOST=10.6.80.35 -REDIS_PORT=6379 -REDIS_PASSWORD=123456 - diff --git a/docker-compose.yml b/docker-compose.yml index 9182b1a..0d78548 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,8 +7,6 @@ services: ports: - "11110:11110" environment: # 更多环境变量配置查看 .env.example - - REDIS_HOST=copilot-redis - - REDIS_PASSWORD=yourpassword - COPILOT_DEBOUNCE=200 # 代码补全请求防抖时间,ms - CODEX_API_BASE=https://api.deepseek.com/beta/v1/completions # 代码补全API地址 - CODEX_API_KEY=yourapikey # 代码补全API密钥 @@ -18,18 +16,9 @@ services: - CHAT_API_MODEL_NAME=deepseek-chat # 聊天补全API模型名称 - CHAT_MAX_TOKENS=4096 # 聊天API最大返回token数 - CODEX_TEMPERATURE=1 # 代码补全API温度, 默认值为:-1, 表示跟随插件动态设置, 如果是deepseek模型,官方推荐设置为1 - depends_on: - - copilot-redis extra_hosts: - "host.docker.internal:host-gateway" - copilot-redis: - container_name: copilot-redis - image: registry.cn-hangzhou.aliyuncs.com/ripper/redis:latest - restart: always - command: redis-server --requirepass yourpassword - environment: - - REDIS_PASSWORD=yourpassword copilot-nginx: container_name: copilot-nginx diff --git a/internal/cache/operation.go b/internal/cache/operation.go index e102369..54c4618 100644 --- a/internal/cache/operation.go +++ b/internal/cache/operation.go @@ -1,26 +1,15 @@ package cache -import ( - "os" -) - var cache Cacheable func init() { - cacheImp := "memory" + cache = NewMemoryMap() - switch cacheImp { - case "redis": - host := os.Getenv("REDIS_HOST") - port := os.Getenv("REDIS_PORT") - psw := os.Getenv("REDIS_PASSWORD") - instance := NewRedisInstance(host, port, psw) - cache = instance - case "memory": - cache = NewMemoryMap() - default: - 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) -- Gitee