feat(push): implement Redis caching for push events and custom channels

- Implement cached queries in GetActivePushEventByKey and GetActivePushChannelByName.
- Set TTL for cached items to 24 hours via activePushEventCacheTTL and activePushChannelCacheTTL constants.
- Implement GORM hooks (AfterSave and AfterDelete) on PushEvent and PushChannel to auto-evict Redis caches, guaranteeing cache consistency.
- Evict Redis caches manually inside API handlers for Create/Update/Delete/Toggle event/channel endpoints.
- Update events.go to query models through the new caching methods.
This commit is contained in:
ryan
2026-06-16 10:19:06 +08:00
parent 9515f0811b
commit 9fa38dcfdc
5 changed files with 108 additions and 8 deletions
+45
View File
@@ -12,6 +12,7 @@ import (
"time"
"github.com/Rain-kl/Wavelet/internal/db"
"gorm.io/gorm"
)
const (
@@ -112,3 +113,47 @@ func GetPushChannelByName(ctx context.Context, name string) (*PushChannel, error
}
return &channel, nil
}
const activePushChannelCacheTTL = 24 * time.Hour
// GetActivePushChannelByName 根据名称获取启用的消息通道 (优先从 Redis 缓存获取)
func GetActivePushChannelByName(ctx context.Context, name string) (*PushChannel, error) {
cacheKey := "push:channel:active:" + name
var channel PushChannel
if db.Redis != nil {
if err := db.GetJSON(ctx, cacheKey, &channel); err == nil {
return &channel, nil
}
}
err := db.DB(ctx).Where("name = ? AND enabled = ?", name, true).First(&channel).Error
if err != nil {
return nil, err
}
if db.Redis != nil {
// 缓存有效时间设置为 24 小时
_ = db.SetJSON(ctx, cacheKey, channel, activePushChannelCacheTTL)
}
return &channel, nil
}
// DeleteActivePushChannelCache 清理启用消息通道的缓存
func DeleteActivePushChannelCache(ctx context.Context, name string) {
if db.Redis != nil {
_ = db.Redis.Del(ctx, db.PrefixedKey("push:channel:active:"+name)).Err()
}
}
// AfterSave GORM 保存后钩子,用于自动清理缓存
func (pc *PushChannel) AfterSave(tx *gorm.DB) error {
DeleteActivePushChannelCache(tx.Statement.Context, pc.Name)
return nil
}
// AfterDelete GORM 删除后钩子,用于自动清理缓存
func (pc *PushChannel) AfterDelete(tx *gorm.DB) error {
DeleteActivePushChannelCache(tx.Statement.Context, pc.Name)
return nil
}
+36 -1
View File
@@ -10,6 +10,7 @@ import (
"time"
"github.com/Rain-kl/Wavelet/internal/db"
"gorm.io/gorm"
)
// PushEvent 系统通知事件模型
@@ -52,12 +53,46 @@ func (pe *PushEvent) Validate() error {
return nil
}
// GetActivePushEventByKey 获取启用的通知事件
const activePushEventCacheTTL = 24 * time.Hour
// GetActivePushEventByKey 获取启用的通知事件 (优先从 Redis 缓存获取)
func GetActivePushEventByKey(ctx context.Context, key string) (*PushEvent, error) {
cacheKey := "push:event:active:" + key
var event PushEvent
if db.Redis != nil {
if err := db.GetJSON(ctx, cacheKey, &event); err == nil {
return &event, nil
}
}
err := db.DB(ctx).Where("event_key = ? AND enabled = ?", key, true).First(&event).Error
if err != nil {
return nil, err
}
if db.Redis != nil {
// 缓存有效时间设置为 24 小时
_ = db.SetJSON(ctx, cacheKey, event, activePushEventCacheTTL)
}
return &event, nil
}
// DeleteActivePushEventCache 清理启用通知事件的缓存
func DeleteActivePushEventCache(ctx context.Context, key string) {
if db.Redis != nil {
_ = db.Redis.Del(ctx, db.PrefixedKey("push:event:active:"+key)).Err()
}
}
// AfterSave GORM 保存后钩子,用于自动清理缓存
func (pe *PushEvent) AfterSave(tx *gorm.DB) error {
DeleteActivePushEventCache(tx.Statement.Context, pe.EventKey)
return nil
}
// AfterDelete GORM 删除后钩子,用于自动清理缓存
func (pe *PushEvent) AfterDelete(tx *gorm.DB) error {
DeleteActivePushEventCache(tx.Statement.Context, pe.EventKey)
return nil
}