feat: activity 并发安全优化
This commit is contained in:
parent
193635c1a9
commit
7c2a825408
|
@ -115,7 +115,7 @@ type Activity[Type, ID generic.Basic] struct {
|
|||
tickerKey string // 定时器 key
|
||||
retention time.Duration // 活动数据保留时间
|
||||
retentionKey string // 保留定时器 key
|
||||
mutex sync.Mutex // 互斥锁
|
||||
mutex sync.RWMutex
|
||||
|
||||
getLastNewDayTime func() time.Time // 获取上次新的一天的时间
|
||||
setLastNewDayTime func(time.Time) // 设置上次新的一天的时间
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package activity
|
||||
|
||||
import "github.com/kercylan98/minotaur/utils/generic"
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/generic"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type none byte
|
||||
|
||||
|
@ -52,59 +55,81 @@ type Controller[Type, ID generic.Basic, Data any, EntityID generic.Basic, Entity
|
|||
entityInitializer func(activityType Type, activityId ID, data map[ID]*DataMeta[Data], entityData map[ID]map[EntityID]*EntityDataMeta[EntityData]) // 实体数据初始化器
|
||||
globalData map[ID]*DataMeta[Data] // 全局数据
|
||||
entityData map[ID]map[EntityID]*EntityDataMeta[EntityData] // 实体数据
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// GetGlobalData 获取特定活动全局数据
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) GetGlobalData(activityId ID) Data {
|
||||
slf.globalDataLoader(activityId)
|
||||
slf.mutex.RLock()
|
||||
defer slf.mutex.RUnlock()
|
||||
return slf.globalData[activityId].Data
|
||||
}
|
||||
|
||||
// GetEntityData 获取特定活动实体数据
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) GetEntityData(activityId ID, entityId EntityID) EntityData {
|
||||
slf.entityDataLoader(activityId, entityId)
|
||||
slf.mutex.RLock()
|
||||
defer slf.mutex.RUnlock()
|
||||
return slf.entityData[activityId][entityId].Data
|
||||
}
|
||||
|
||||
// GetAllEntityData 获取特定活动所有实体数据
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) GetAllEntityData(activityId ID) map[EntityID]EntityData {
|
||||
var entities = make(map[EntityID]EntityData)
|
||||
slf.mutex.RLock()
|
||||
for k, v := range slf.entityData[activityId] {
|
||||
entities[k] = v.Data
|
||||
}
|
||||
slf.mutex.RUnlock()
|
||||
return entities
|
||||
}
|
||||
|
||||
// IsOpen 活动是否开启
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) IsOpen(activityId ID) bool {
|
||||
slf.mutex.RLock()
|
||||
activity, exist := slf.activities[activityId]
|
||||
slf.mutex.RUnlock()
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
activity.mutex.RLock()
|
||||
defer activity.mutex.RUnlock()
|
||||
return activity.state == stateStarted
|
||||
}
|
||||
|
||||
// IsShow 活动是否展示
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) IsShow(activityId ID) bool {
|
||||
slf.mutex.RLock()
|
||||
activity, exist := slf.activities[activityId]
|
||||
slf.mutex.RUnlock()
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
activity.mutex.RLock()
|
||||
defer activity.mutex.RUnlock()
|
||||
return activity.state == stateUpcoming || (activity.state == stateEnded && activity.tl.HasState(stateExtendedShowEnded))
|
||||
}
|
||||
|
||||
// IsOpenOrShow 活动是否开启或展示
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) IsOpenOrShow(activityId ID) bool {
|
||||
slf.mutex.RLock()
|
||||
activity, exist := slf.activities[activityId]
|
||||
slf.mutex.RUnlock()
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
|
||||
activity.mutex.RLock()
|
||||
defer activity.mutex.RUnlock()
|
||||
return activity.state == stateStarted || activity.state == stateUpcoming || (activity.state == stateEnded && activity.tl.HasState(stateExtendedShowEnded))
|
||||
}
|
||||
|
||||
// Refresh 刷新活动
|
||||
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) Refresh(activityId ID) {
|
||||
slf.mutex.RLock()
|
||||
activity, exist := slf.activities[activityId]
|
||||
slf.mutex.RUnlock()
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -32,11 +32,15 @@ func regController[Type, ID generic.Basic, Data any, EntityID generic.Basic, Ent
|
|||
defer controllersLock.Unlock()
|
||||
controller.activities = make(map[ID]*Activity[Type, ID])
|
||||
controllerGlobalDataReader = append(controllerGlobalDataReader, func(handler func(activityType, activityId, data any)) {
|
||||
controller.mutex.RLock()
|
||||
defer controller.mutex.RUnlock()
|
||||
for activityId, data := range controller.globalData {
|
||||
handler(activityType, activityId, data)
|
||||
}
|
||||
})
|
||||
controllerEntityDataReader = append(controllerEntityDataReader, func(handler func(activityType, activityId, entityId, data any)) {
|
||||
controller.mutex.RLock()
|
||||
defer controller.mutex.RUnlock()
|
||||
for activityId, entities := range controller.entityData {
|
||||
for entityId, data := range entities {
|
||||
handler(activityType, activityId, entityId, data)
|
||||
|
@ -51,6 +55,8 @@ func regController[Type, ID generic.Basic, Data any, EntityID generic.Basic, Ent
|
|||
tof = tof.Elem()
|
||||
}
|
||||
controller.globalDataLoader = func(activityId any) {
|
||||
controller.mutex.Lock()
|
||||
defer controller.mutex.Unlock()
|
||||
var id = activityId.(ID)
|
||||
if _, exist := controller.globalData[id]; exist {
|
||||
return
|
||||
|
@ -71,6 +77,8 @@ func regController[Type, ID generic.Basic, Data any, EntityID generic.Basic, Ent
|
|||
tof = tof.Elem()
|
||||
}
|
||||
controller.entityDataLoader = func(activityId any, entityId any) {
|
||||
controller.mutex.Lock()
|
||||
defer controller.mutex.Unlock()
|
||||
var id, eid = activityId.(ID), entityId.(EntityID)
|
||||
entities, exist := controller.entityData[id]
|
||||
if !exist {
|
||||
|
@ -92,6 +100,7 @@ func regController[Type, ID generic.Basic, Data any, EntityID generic.Basic, Ent
|
|||
controllers[activityType] = controller
|
||||
controllerRegisters[activityType] = func(activityType, activityId any) (act any, optionInitCallback func(activity any)) {
|
||||
var at, ai = activityType.(Type), activityId.(ID)
|
||||
controller.mutex.Lock()
|
||||
activity, exist := controller.activities[ai]
|
||||
if !exist {
|
||||
activity = &Activity[Type, ID]{
|
||||
|
@ -107,6 +116,7 @@ func regController[Type, ID generic.Basic, Data any, EntityID generic.Basic, Ent
|
|||
},
|
||||
}
|
||||
}
|
||||
controller.mutex.Unlock()
|
||||
controller.activities[activity.id] = activity
|
||||
return activity, func(activity any) {
|
||||
act := activity.(*Activity[Type, ID])
|
||||
|
@ -120,6 +130,8 @@ func regController[Type, ID generic.Basic, Data any, EntityID generic.Basic, Ent
|
|||
}
|
||||
controllerReset[activityType] = func(activityId any) {
|
||||
var id = activityId.(ID)
|
||||
controller.mutex.Lock()
|
||||
defer controller.mutex.Unlock()
|
||||
delete(controller.globalData, id)
|
||||
delete(controller.entityData, id)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue