126 lines
2.9 KiB
Go
126 lines
2.9 KiB
Go
package com
|
|
|
|
import (
|
|
"time"
|
|
|
|
"mongo.games.com/goserver/core/basic"
|
|
"mongo.games.com/goserver/core/logger"
|
|
"mongo.games.com/goserver/core/task"
|
|
)
|
|
|
|
// NewListMgr 创建一个列表管理器
|
|
// cacheTime 缓存时间,单位秒
|
|
// loadFunc 加载函数
|
|
func NewListMgr[T any](cacheTime func() int64, loadFunc func(platform string, index int32) ([]T, error)) *ListMgr[T] {
|
|
return &ListMgr[T]{
|
|
platform: make(map[string]map[int32]*DataItem[T]),
|
|
LoadFunc: loadFunc,
|
|
CacheTime: cacheTime,
|
|
}
|
|
}
|
|
|
|
type funcCall[T any] func([]T, error)
|
|
|
|
type DataItem[T any] struct {
|
|
Ts int64 // 更新时间
|
|
List []T
|
|
cb []funcCall[T]
|
|
}
|
|
|
|
type ListMgr[T any] struct {
|
|
platform map[string]map[int32]*DataItem[T]
|
|
|
|
// 数据库查询方法
|
|
// 参数 平台id,类型
|
|
LoadFunc func(string, int32) ([]T, error)
|
|
CacheTime func() int64
|
|
}
|
|
|
|
// Get 从缓存中获取数据
|
|
func (r *ListMgr[T]) Get(platform string, index int32, f func([]T, error)) {
|
|
tp := r.platform[platform]
|
|
if tp == nil {
|
|
r.platform[platform] = map[int32]*DataItem[T]{}
|
|
}
|
|
item := r.platform[platform][index]
|
|
if item != nil {
|
|
f(item.List, nil)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Take 从缓存中获取数据,如果缓存中没有数据或缓存过期,则从数据库中获取数据
|
|
func (r *ListMgr[T]) Take(platform string, index int32, f func([]T, error)) {
|
|
tp := r.platform[platform]
|
|
if tp == nil {
|
|
r.platform[platform] = map[int32]*DataItem[T]{}
|
|
}
|
|
item := r.platform[platform][index]
|
|
if item != nil && time.Now().Unix()-item.Ts < r.CacheTime() {
|
|
f(item.List, nil)
|
|
return
|
|
}
|
|
|
|
if item == nil {
|
|
item = &DataItem[T]{
|
|
cb: []funcCall[T]{f},
|
|
}
|
|
r.platform[platform][index] = item
|
|
} else {
|
|
if len(item.cb) > 0 {
|
|
item.cb = append(item.cb, f)
|
|
return
|
|
} else {
|
|
item.cb = []funcCall[T]{f}
|
|
}
|
|
}
|
|
|
|
var list []T
|
|
var err error
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
list, err = r.LoadFunc(platform, index)
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
|
r.platform[platform][index] = &DataItem[T]{
|
|
List: list,
|
|
Ts: time.Now().Unix(),
|
|
}
|
|
for _, v := range item.cb {
|
|
v(list, err)
|
|
}
|
|
})).Start()
|
|
}
|
|
|
|
// UpdateCache 更新缓存
|
|
// 重新获取数据
|
|
func (r *ListMgr[T]) UpdateCache(platform string, index int32) {
|
|
tp := r.platform[platform]
|
|
if tp == nil {
|
|
r.platform[platform] = map[int32]*DataItem[T]{}
|
|
}
|
|
item := r.platform[platform][index]
|
|
if item == nil {
|
|
item = &DataItem[T]{
|
|
cb: []funcCall[T]{},
|
|
}
|
|
r.platform[platform][index] = item
|
|
}
|
|
|
|
var list []T
|
|
var err error
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
list, err = r.LoadFunc(platform, index)
|
|
if err != nil {
|
|
logger.Logger.Errorf("UpdateCache LoadFunc error:%v", err)
|
|
}
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
|
if err == nil {
|
|
r.platform[platform][index] = &DataItem[T]{
|
|
List: list,
|
|
Ts: time.Now().Unix(),
|
|
}
|
|
}
|
|
})).Start()
|
|
}
|