数据保存加锁

This commit is contained in:
hahwu 2026-02-24 11:35:06 +08:00
parent f026927a10
commit 437eeac1dd
4 changed files with 21 additions and 41 deletions

View File

@ -270,7 +270,7 @@ func ReqGmCommand_(player *Player, Command string) error {
N: ChampshipMod.GetN(),
},
End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除
HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK,
HandleType: MsgMod.HANDLE_MOD_CHAMPSHIP_INRANK,
}
SendMsgToCenterAsync(m)
case "resetUserInfo":

View File

@ -26,7 +26,7 @@ type MessageMiddleware func(MessageHandlerFunc) MessageHandlerFunc
var save_msg_type = []int{
msg.HANDLE_MOD_PLAYER_MSG,
msg.HANDLE_MDO_CHAMPSHIP_INRANK,
msg.HANDLE_MOD_CHAMPSHIP_INRANK,
msg.HANDLE_MOD_USER_VAR_SET,
}
@ -125,31 +125,6 @@ func (m *MessageMgr) MessageMgrInit() {
m.Use(TimeoutMiddleware(5 * time.Second))
m.NodeRegister()
m.CenterRegister()
FixBug()
}
func FixBug() {
messageMgrData := getMessageData()
// 先更新 PlayerList需要加锁
G_GameLogicPtr.MessageMgr.lock.Lock()
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
now := GoUtil.Now()
for k, v := range messageMgrData.MessageList {
if k < 100000 {
delete(messageMgrData.MessageList, k)
continue
}
// 反向遍历以安全删除元素
for i := len(v.Messages) - 1; i >= 0; i-- {
if v.Messages[i].Type == msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY || (v.Messages[i].End != 0 && v.Messages[i].End < now) {
// 删除消息
v.Messages = append(v.Messages[:i], v.Messages[i+1:]...)
}
}
if len(v.Messages) == 0 {
delete(messageMgrData.MessageList, k)
}
}
}
// 注册处理器
@ -168,7 +143,7 @@ func (m *MessageMgr) NodeRegister() {
func (m *MessageMgr) CenterRegister() {
if conf.Server.ServerType == "center" {
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_LOGIN, MessageHandlerFunc(PlayerLoginHandler))
m.RegisterHandler(msg.HANDLE_MDO_PLAYER_LOGOUT, MessageHandlerFunc(PlayerLogoutHandler))
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_LOGOUT, MessageHandlerFunc(PlayerLogoutHandler))
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_MSG, MessageHandlerFunc(CenterPlayerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_COMSUME_MSG, MessageHandlerFunc(ComsumerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_VAR_SET, MessageHandlerFunc(SetVarDataHandler))
@ -176,7 +151,7 @@ func (m *MessageMgr) CenterRegister() {
m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_SET, MessageHandlerFunc(SetUserVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_GET, MessageHandlerFunc(GetUserVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_CATNIP_PARTNER, MessageHandlerFunc(CatnipPartnerHandler))
m.RegisterHandler(msg.HANDLE_MDO_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_INFO, MessageHandlerFunc(ChampshipRankInfoHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_LIST, MessageHandlerFunc(ChampshipRankListHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_PRE_RANK, MessageHandlerFunc(ChampshipRankPreHandler))
@ -885,9 +860,6 @@ func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) {
// 保存消息到本地
func saveMessage(m *msg.Msg) error {
G_GameLogicPtr.MessageMgr.lock.Lock()
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
// 使用不加锁的内部方法,避免死锁
messages := getMessgeUnsafe(int64(m.To))
messages.mu.Lock()
defer messages.mu.Unlock()
@ -944,7 +916,6 @@ func deleteMessage(m *msg.Msg) error {
}
messages := getMessge(int64(m.To))
messages.mu.Lock()
defer messages.mu.Unlock()
// 使用更安全的方式删除元素找到索引后再删除避免在range中修改切片
foundIndex := -1
@ -965,12 +936,21 @@ func deleteMessage(m *msg.Msg) error {
messages.Messages[len(messages.Messages)-1] = nil // 清除最后一个元素的引用
messages.Messages = messages.Messages[:len(messages.Messages)-1]
}
if len(messages.Messages) == 0 {
shouldDelete := len(messages.Messages) == 0
messages.mu.Unlock() // 先释放 messages.mu 锁,避免死锁
if shouldDelete {
// 如果消息列表为空,则删除该玩家的消息列表
messageMgrData := getMessageData()
G_GameLogicPtr.MessageMgr.lock.Lock()
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
delete(messageMgrData.MessageList, int64(m.To))
// 双重检查:再次确认消息列表是否为空(防止在锁释放期间有新消息添加)
if list, ok := messageMgrData.MessageList[int64(m.To)]; ok {
list.mu.Lock()
if len(list.Messages) == 0 {
delete(messageMgrData.MessageList, int64(m.To))
}
list.mu.Unlock()
}
}
return nil
}

View File

@ -41,14 +41,14 @@ const (
HANDLE_MOD_PLAYER_LOGIN = 20003 // 玩家登录消息
HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息
HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息
HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息
HANDLE_MOD_PLAYER_LOGOUT = 20006 // 玩家登出消息
HANDLE_MOD_VAR_GET = 20007 // 获取变量
HANDLE_MOD_VAR_SET = 20008 // 设置变量
HANDLE_MOD_CATNIP_PARTNER = 20009 // 猫薄荷伙伴
HANDLE_MOD_USER_VAR_GET = 20010 // 获取玩家变量
HANDLE_MOD_USER_VAR_SET = 20011 // 设置玩家变量
HANDLE_MOD_REPLY_PLAYER_MSG = 20012 // 回复玩家消息
HANDLE_MDO_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜
HANDLE_MOD_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜
HANDLE_MOD_CHAMPSHIP_RANK_INFO = 20014 // 锦标赛排名信息
HANDLE_MOD_CHAMPSHIP_RANK_LIST = 20015 // 锦标赛排行榜
HANDLE_MOD_CHAMPSHIP_PRE_RANK = 20016 // 锦标赛上期排名

View File

@ -473,7 +473,7 @@ func (p *Player) ClearData() {
G_GameLogicPtr.DelPlayer(p)
SendMsgToCenterAsync(&MsgMod.Msg{
From: Uid,
HandleType: MsgMod.HANDLE_MDO_PLAYER_LOGOUT,
HandleType: MsgMod.HANDLE_MOD_PLAYER_LOGOUT,
})
}
@ -1043,7 +1043,7 @@ func (p *Player) HandleInChampshipRank() {
N: ChampshipMod.GetN(),
},
End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除
HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK,
HandleType: MsgMod.HANDLE_MOD_CHAMPSHIP_INRANK,
}
SendMsgToCenterAsync(m)
}