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