// Copyright 2023 ROC. All rights reserved. // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. package cache import ( "context" "time" "github.com/redis/rueidis" "github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/pkg/utils" ) var ( _webCache core.WebCache = (*webCache)(nil) _appCache core.AppCache = (*appCache)(nil) ) type appCache struct { cscExpire time.Duration c rueidis.Client } type webCache struct { core.AppCache c rueidis.Client unreadMsgExpire int64 } func (s *appCache) Get(key string) ([]byte, error) { res, err := rueidis.MGetCache(s.c, context.Background(), s.cscExpire, []string{key}) if err != nil { return nil, err } message := res[key] return message.AsBytes() } func (s *appCache) Set(key string, data []byte, ex int64) error { ctx := context.Background() cmd := s.c.B().Set().Key(key).Value(utils.String(data)) if ex > 0 { return s.c.Do(ctx, cmd.ExSeconds(ex).Build()).Error() } return s.c.Do(ctx, cmd.Build()).Error() } func (s *appCache) SetNx(key string, data []byte, ex int64) error { ctx := context.Background() cmd := s.c.B().Set().Key(key).Value(utils.String(data)).Nx() if ex > 0 { return s.c.Do(ctx, cmd.ExSeconds(ex).Build()).Error() } return s.c.Do(ctx, cmd.Build()).Error() } func (s *appCache) Delete(keys ...string) (err error) { if len(keys) != 0 { err = s.c.Do(context.Background(), s.c.B().Del().Key(keys...).Build()).Error() } return } func (s *appCache) DelAny(pattern string) (err error) { var ( keys []string cursor uint64 entry rueidis.ScanEntry ) ctx := context.Background() for { cmd := s.c.B().Scan().Cursor(cursor).Match(pattern).Count(50).Build() if entry, err = s.c.Do(ctx, cmd).AsScanEntry(); err != nil { return } keys = append(keys, entry.Elements...) if entry.Cursor != 0 { cursor = entry.Cursor continue } break } if len(keys) != 0 { err = s.c.Do(ctx, s.c.B().Del().Key(keys...).Build()).Error() } return } func (s *appCache) Exist(key string) bool { cmd := s.c.B().Exists().Key(key).Build() count, _ := s.c.Do(context.Background(), cmd).AsInt64() return count > 0 } func (s *appCache) Keys(pattern string) (res []string, err error) { ctx, cursor := context.Background(), uint64(0) for { cmd := s.c.B().Scan().Cursor(cursor).Match(pattern).Count(50).Build() entry, err := s.c.Do(ctx, cmd).AsScanEntry() if err != nil { return nil, err } res = append(res, entry.Elements...) if entry.Cursor != 0 { cursor = entry.Cursor continue } break } return } func (s *webCache) GetUnreadMsgCountResp(uid int64) ([]byte, error) { key := conf.KeyUnreadMsg.Get(uid) return s.Get(key) } func (s *webCache) PutUnreadMsgCountResp(uid int64, data []byte) error { return s.Set(conf.KeyUnreadMsg.Get(uid), data, s.unreadMsgExpire) } func (s *webCache) DelUnreadMsgCountResp(uid int64) error { return s.Delete(conf.KeyUnreadMsg.Get(uid)) } func (s *webCache) ExistUnreadMsgCountResp(uid int64) bool { return s.Exist(conf.KeyUnreadMsg.Get(uid)) } func (s *webCache) PutHistoryMaxOnline(newScore int) (int, error) { ctx := context.Background() cmd := s.c.B().Zadd(). Key(conf.KeySiteStatus). Gt().ScoreMember(). ScoreMember(float64(newScore), conf.KeyHistoryMaxOnline).Build() if err := s.c.Do(ctx, cmd).Error(); err != nil { return 0, err } cmd = s.c.B().Zscore().Key(conf.KeySiteStatus).Member(conf.KeyHistoryMaxOnline).Build() if score, err := s.c.Do(ctx, cmd).ToFloat64(); err == nil { return int(score), nil } else { return 0, err } } func newAppCache() *appCache { return &appCache{ cscExpire: conf.CacheSetting.CientSideCacheExpire, c: conf.MustRedisClient(), } } func newWebCache(ac core.AppCache) *webCache { return &webCache{ AppCache: ac, c: conf.MustRedisClient(), unreadMsgExpire: conf.CacheSetting.UnreadMsgExpire, } }