name5566 / leaf

A game server framework in Go (golang)
Apache License 2.0
5.27k stars 1.31k forks source link

请问一下 skeleton.AfterFunc两个一起用会造成阻塞 #118

Closed jjjjilyf closed 6 years ago

jjjjilyf commented 6 years ago

用法如下:可以看到有两个黑体字的地方调用了AfterFunc这个函数,但是在定时从数据库读取数据的时候,如果同时也执行了一下定时保存玩家数据,那么服务器就失去响应了,需要在服务器的窗口按一下ESC才会恢复响应,请大神帮忙看下是哪里用错了?

func (m *Module) OnInit() {
    m.Skeleton = skeleton
    mongoinit()
    initDB()
    **go scheCheckRedisUser()**
}
// 定时检测
**func scheCheckRedisUser() {**
    log.Debug("--定时检测内存中离线玩家数据")
    //cronExpr, err := timer.NewCronExpr("1 * * * * *")
    //if err != nil {
    //  return
    //}

    n := MaxGoal/StageGoal
    skeleton.AfterFunc(time.Second*20, func(){
        log.Debug("CronFunc")
        **scheCheckRedisUser()**
        cronClearMatchOverPlayer(n)
        cronLoadPlayerFromDB(n)
    })
    //timer.Stop()
}
func (user *User) autoSaveDB(){
    log.Debug("======定时保存数据库")
    const duration = 10 * time.Second

    // 保存数据库
    **user.saveDBTimer = skeleton.AfterFunc(duration, func() {**
        log.Debug("autoSaveDB AfterFunc1", user.UserData(), user.data)
        data := util.DeepClone(user.data)
        //log.Debug("autoSaveDB AfterFunc2", user.UserData(), user.data)
        user.Go(func() {
            dbm := mongoDB.Ref()
            defer  mongoDB.UnRef(dbm)
            d := data.(*UserData)
            userID := d.BD.UserID
            log.Debug("OPOP", d.BD.CTime,d.BD.LTime, d.BD.LTime, d.BD.CTime)
            _, err := dbm.DB("soccerdb").C("users").UpsertId(userID, data)
            if err != nil {
                log.Error("auto save %v data error: %v", userID, err)
            }
        }, func(){
            user.autoSaveDB()
        })
    })
}
jjjjilyf commented 6 years ago

为什么MongoDB失去会失去响应,只开了服务器和一个玩家,难道就承受不了了吗?且在失去响应的时候,按下Esc就刷刷刷的刷新出打印,又恢复正常了,在Cmd窗口按Esc意味着什么?有什么特殊的意义吗?类似于Ctrl+C?Google了下 没搜到答案。

jjjjilyf commented 6 years ago

MongoDB失去响应的问题找到了,可能是退出服务器的时候,在Module的onDestroy里没有调用mongoDestroy()函数关闭mongodb的连接。