123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- package readcache
- import (
- "fmt"
- "leafstalk/covenant/monitor"
- "leafstalk/module"
- "leafstalk/otherutils"
- "reflect"
- "strconv"
- "time"
- cach2 "github.com/patrickmn/go-cache"
- )
- type SameStructCache struct {
- Name string
- AllPlayers *cach2.Cache
- tokens otherutils.RoutineTokens
- loadFilter otherutils.FilterInt64
- skeleton *module.Skeleton
- Load func(id int64) (interface{}, error)
- New func(playerId int64) interface{}
- PrePocess func(interface{})
- }
- func NewCache(skeleton *module.Skeleton) *SameStructCache {
- c := new(SameStructCache)
- c.skeleton = skeleton
- return c
- }
- type callBackFun struct {
- fprocess func(p interface{})
- fErrProcess func(playerId int64, errorCode int)
- }
- func (c *SameStructCache) Init(load func(id int64) (interface{}, error), newObj func(playerId int64) interface{}, preProcess func(interface{})) {
- c.AllPlayers = cach2.New(5*time.Minute, 10*time.Minute)
- c.tokens.Init(10)
- c.Load = load
- c.New = newObj
- c.PrePocess = preProcess
- }
- func (c *SameStructCache) GetCacheData(playerID int64) interface{} {
- k := strconv.FormatInt(playerID, 10)
- if v, ok := c.AllPlayers.Get(k); ok {
- return v
- }
- return nil
- }
- func (c *SameStructCache) SetCacheData(playerID int64, v interface{}) {
- k2 := strconv.FormatInt(playerID, 10)
- c.AllPlayers.SetDefault(k2, v)
- }
- func (c *SameStructCache) LoadAndProcess(playerId int64, fprocess func(p interface{}), fErrProcess func(playerId int64, errorCode int)) {
- st := time.Now()
- //找到玩家
- p := c.GetCacheData(playerId)
- if p != nil {
- c.SetCacheData(playerId, p)
- c.PrePocess(p)
- fprocess(p)
- monitor.GoLoadTimeoutWarn(fmt.Sprintf("%s.LoadAndProcess", c.Name), playerId, st)
- return
- }
- //正在加载
- if c.loadFilter.IsExist(playerId) {
- t := new(callBackFun)
- t.fprocess = fprocess
- t.fErrProcess = fErrProcess
- c.loadFilter.AppendTask(playerId, t)
- return
- }
- c.loadFilter.Add(playerId)
- var err error
- c.skeleton.Go(func() {
- //协程加载
- c.tokens.Get()
- defer c.tokens.Release()
- p, err = c.Load(playerId)
- }, func() {
- defer func() {
- s := c.loadFilter.Remove(playerId)
- for _, v := range s {
- cft := v.(*callBackFun)
- if err != nil {
- cft.fErrProcess(playerId, 11)
- } else {
- cft.fprocess(p)
- }
- }
- monitor.GoLoadTimeoutWarn(fmt.Sprintf("%s.LoadAndProcess", c.Name), playerId, st)
- }()
- if err != nil {
- fErrProcess(playerId, 11)
- return
- }
- if IsNil(p) || p == nil {
- p = c.New(playerId)
- }
- c.SetCacheData(playerId, p)
- c.PrePocess(p)
- fprocess(p)
- })
- }
- func IsNil(i interface{}) bool {
- vi := reflect.ValueOf(i)
- if vi.Kind() == reflect.Ptr {
- return vi.IsNil()
- }
- return false
- }
|