Leaf游戲服務器簡析(一)之模塊生命周期

Module(模塊)的生命周期

使用leaf開發(fā)游戲服務器由多個模塊組成,模塊的定義如下:

// leaf/module.go
type Module interface{
    OnInit()
    OnDestroy()
    Run(closeSig chan bool)
}

模塊需要實現(xiàn)OnInit(),OnDestroy(),Run(closeSig chan bool)三個接口,這三個接口定義了模塊生命周期的行為.

以官方項目LeafServer為例說明模塊的運行機制

// server/main.go (片段)
// LeafServer程序的入口
func main() {
    // ......
    leaf.Run(
        game.Module,
        gate.Module,
        login.Module,
    )
}

程序入口調用leaf.Run(),在Run函數里面分別注冊了game.Module, gate.Module, login.Module,在leaf源碼里我們可以看到leaf.Run()的行為:

// leaf/leaf.go
func Run(mods ...module.Module) {
    // ...
    // module
    for i := 0; i < len(mods); i++ {
        module.Register(mods[i])
    }
    module.Init()

    // ...

    // 通過channel c來監(jiān)聽來自操作系統(tǒng)的終止指令
    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt, os.Kill)
    // 等待終止指令, 一旦讀到終止指令則執(zhí)行之后的代碼,module.Destroy()將調用各個模塊的OnDestroy()
    sig := <-c

    // ...
    module.Destroy()
}

函數參數mods是我們傳進來的各個模塊,module.Register(mod)將我們的模塊注冊到module中去:

// leaf/module.go
var mods []*module
func Register(mi Module) {
    m := new(module)
    m.mi = mi
    m.closeSig = make(chan bool, 1)
    mods = append(mods, m)
}

之后調用module.Init()對我們注冊的模塊進行初始化,進入OnInit()周期,之后對每個模塊開啟goroutine來進入各模塊的Run()周期:

// leaf/module.go

// 初始化
func Init() {
    for i := 0; i < len(mods); i++ {
        mods[i].mi.OnInit()
    }

    for i := 0; i < len(mods); i++ {
        m := mods[i]
        m.wg.Add(1)
        // 開啟goroutine
        go run(m)
    }
}

func run(m *module) {
    m.mi.Run(m.closeSig)
    m.wg.Done()
}

而Module生命周期的結束階段則在系統(tǒng)讀取到終止命令時執(zhí)行module.Destroy()來進行模塊的銷毀邏輯:

// leaf/module.go

func Destroy() {
    for i := len(mods) - 1; i >= 0; i-- {
        m := mods[i]
        m.closeSig <- true
        m.wg.Wait()
        destroy(m)
    }
}

func destroy(m *module) {
    defer func() {
        if r := recover(); r != nil {
            if conf.LenStackBuf > 0 {
                buf := make([]byte, conf.LenStackBuf)
                l := runtime.Stack(buf, false)
                log.Error("%v: %s", r, buf[:l])
            } else {
                log.Error("%v", r)
            }
        }
    }()
    m.mi.OnDestroy()
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容