Module(模塊)的生命周期
使用leaf開發(fā)游戲服務(wù)器由多個(gè)模塊組成,模塊的定義如下:
// leaf/module.go
type Module interface{
OnInit()
OnDestroy()
Run(closeSig chan bool)
}
模塊需要實(shí)現(xiàn)OnInit(),OnDestroy(),Run(closeSig chan bool)三個(gè)接口,這三個(gè)接口定義了模塊生命周期的行為.
以官方項(xiàng)目LeafServer為例說(shuō)明模塊的運(yùn)行機(jī)制
// server/main.go (片段)
// LeafServer程序的入口
func main() {
// ......
leaf.Run(
game.Module,
gate.Module,
login.Module,
)
}
程序入口調(diào)用leaf.Run(),在Run函數(shù)里面分別注冊(cè)了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()
// ...
// 通過(guò)channel c來(lái)監(jiān)聽來(lái)自操作系統(tǒng)的終止指令
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)
// 等待終止指令, 一旦讀到終止指令則執(zhí)行之后的代碼,module.Destroy()將調(diào)用各個(gè)模塊的OnDestroy()
sig := <-c
// ...
module.Destroy()
}
函數(shù)參數(shù)mods是我們傳進(jìn)來(lái)的各個(gè)模塊,module.Register(mod)將我們的模塊注冊(cè)到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)
}
之后調(diào)用module.Init()對(duì)我們注冊(cè)的模塊進(jìn)行初始化,進(jìn)入OnInit()周期,之后對(duì)每個(gè)模塊開啟goroutine來(lái)進(jìn)入各模塊的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生命周期的結(jié)束階段則在系統(tǒng)讀取到終止命令時(shí)執(zhí)行module.Destroy()
來(lái)進(jìn)行模塊的銷毀邏輯:
// 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()
}