go_dreamfactory/modules/redis/expiredcomp.go

91 lines
1.8 KiB
Go

package redis
import (
"context"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/redis"
"sync"
"time"
)
///过期数据管理组件
type ExpiredComp struct {
cbase.ModuleCompBase
redis redis.ISys
mu sync.RWMutex
data map[string]*ModelDataExpired
}
//组件初始化接口
func (this *ExpiredComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.ModuleCompBase.Init(service, module, comp, opt)
this.data = make(map[string]*ModelDataExpired, 1024)
return
}
func (this *ExpiredComp) Start() (err error) {
err = this.ModuleCompBase.Start()
go this.run()
return
}
func (this *ExpiredComp) UpDateModel(key string, childs map[string]struct{}, expired time.Duration) {
this.mu.RLock()
exp, ok := this.data[key]
this.mu.RUnlock()
if ok {
exp.keys = childs
exp.expired = time.Now().Add(expired)
} else {
exp = &ModelDataExpired{
key: key,
keys: childs,
expired: time.Now().Add(expired),
}
this.mu.Lock()
this.data[key] = exp
this.mu.Unlock()
}
}
//定时清理过期数据
func (this *ExpiredComp) run() {
timer := time.NewTicker(time.Minute * 1)
defer timer.Stop()
for {
select {
case <-timer.C:
this.scanning()
break
}
}
}
//扫描过期
func (this *ExpiredComp) scanning() {
now := time.Now()
this.mu.Lock()
temp := make([]*ModelDataExpired, 0, len(this.data))
for k, v := range this.data {
if v.expired.Before(now) { //过期
temp = append(temp, v)
delete(this.data, k)
}
}
this.mu.Unlock()
ctx := context.Background()
pipe := this.redis.Pipeline()
for _, v := range temp {
pipe.Del(ctx, v.key)
if v.keys != nil {
for k1, _ := range v.keys {
pipe.Del(ctx, k1)
}
}
}
if _, err := pipe.Exec(ctx); err != nil {
}
}