-
Notifications
You must be signed in to change notification settings - Fork 7
/
module.go
186 lines (163 loc) · 5.21 KB
/
module.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Package module 基础模块,实现了基本的模块接口,利于上层使用 micserver ,在业务中自定义模块时,
// 可以直接继承该基础模块,继承于基础模块(使用匿名成员实现)的上层业务模块,
// 即实现了 IModule 接口。例如:
// type FooModule struct {
// module.BaseModule
// ...
// }
// 需要注意的是有些方法在重载时,需要在重载中调用父类的该方法,且调用顺序有要求:
// 如果你需要在例如 AfterInitModule() 中增加逻辑,请使用如下顺序:
// func (bm *FooModule) AfterInitModule() {
// // 先调用父类方法
// bm.BaseModule.AfterInitModule()
// // 其他逻辑
// ...
// }
// 如果你需要在例如 KillModule() 中增加逻辑,请使用如下顺序:
// func (bm *FooModule) KillModule() {
// // 其他逻辑
// ...
// // 最后调用父类方法
// bm.BaseModule.KillModule()
// }
package module
import (
"time"
"github.com/liasece/micserver/base"
"github.com/liasece/micserver/conf"
"github.com/liasece/micserver/log"
"github.com/liasece/micserver/roc"
"github.com/liasece/micserver/server"
"github.com/liasece/micserver/util"
"github.com/liasece/micserver/util/hash"
"github.com/liasece/micserver/util/monitor"
"github.com/liasece/micserver/util/timer"
"github.com/liasece/micserver/util/uid"
)
// IModule 一个模块应具备的接口
type IModule interface {
base.IModule
InitModule(conf.ModuleConfig) error
BindSubnet(map[string]string)
AfterInitModule()
TopRunner()
KillModule()
IsStopped() bool
GetConfiger() *conf.ModuleConfig
ROCCallNR(callpath *roc.Path, callarg []byte) error
ROCCallBlock(callpath *roc.Path, callarg []byte) ([]byte, error)
}
// BaseModule 基础模块
type BaseModule struct {
*log.Logger
TimerManager timer.Manager
server.Server
// 模块配置
configer *conf.ModuleConfig
// 模块的负载
load monitor.Load
moduleID string
moduleIDHash uint32
moduleType string
moduleNum int
hasKilledModule bool
hasStopped bool
lastCheckLoad int64
}
// InitModule 初始化模块
func (bm *BaseModule) InitModule(configer conf.ModuleConfig) error {
{
// check module state
if bm.GetModuleID() == "" {
uid, err := uid.GenUniqueID(0)
if err != nil {
return err
}
bm.SetModuleID(uid)
}
}
bm.configer = &configer
// 初始化logger
if bm.configer.ExistInModule(conf.LogWholePath) {
bm.Logger = log.NewLogger(nil, log.Options().NoConsole(bm.configer.GetBool(conf.IsDaemon)).FilePaths(bm.configer.GetString(conf.LogWholePath)))
bm.SetLogName(bm.moduleID)
} else {
bm.Logger = log.GetDefaultLogger().Clone()
bm.Logger.SetLogName(bm.moduleID)
}
bm.Syslog("[BaseModule.InitModule] Module initializing...")
bm.Server.SetLogger(bm.Logger)
bm.Server.Init(bm.moduleID)
bm.Server.InitSubnet(bm.configer)
// gateway初始化
if gateaddr := bm.configer.GetString(conf.GateTCPAddr); gateaddr != "" {
bm.Server.InitGate(gateaddr)
}
bm.TimerManager.RegTimer(time.Second*5, 0, false, bm.watchLoadToLog)
return nil
}
// AfterInitModule 在初始化完成后调用
func (bm *BaseModule) AfterInitModule() {
bm.Syslog("[BaseModule.AfterInitModule] Module initialization complete", log.String("ModuleID", bm.GetModuleID()))
}
// GetConfiger 获取模块的配置
func (bm *BaseModule) GetConfiger() *conf.ModuleConfig {
return bm.configer
}
// GetModuleID 获取模块的ID,模块的ID有模块类型和模块编号确定,如
// moduleid = fmt.Sprintf("%s%d", typ, num)
func (bm *BaseModule) GetModuleID() string {
return bm.moduleID
}
// SetModuleID 设置模块的ID,需要谨慎使用,不可在模块运行起来后设置!
func (bm *BaseModule) SetModuleID(id string) {
bm.moduleID = id
bm.moduleType = util.GetModuleIDType(id)
bm.moduleNum = util.GetModuleIDNum(id)
bm.moduleIDHash = hash.GetHash([]byte(id))
}
// GetModuleType 获取模块类型
func (bm *BaseModule) GetModuleType() string {
return bm.moduleType
}
// GetModuleNum 获取模块编号
func (bm *BaseModule) GetModuleNum() int {
return bm.moduleNum
}
// GetModuleIDHash 获取模块ID哈希值
func (bm *BaseModule) GetModuleIDHash() uint32 {
return bm.moduleIDHash
}
// GenUniqueID 在该模块环境下生成一个UUID,这个UUID保证在本模块中是唯一的
func (bm *BaseModule) GenUniqueID() (string, error) {
return uid.GenUniqueID(uint16(bm.GetModuleIDHash()))
}
// KillModule 当模块被中止时调用
func (bm *BaseModule) KillModule() {
bm.Syslog("[BaseModule] Killing module...")
bm.Server.Stop()
bm.hasKilledModule = true
bm.TimerManager.KillRegister()
// 退出完成
bm.hasStopped = true
}
// IsStopped 判断模块是否已中止
func (bm *BaseModule) IsStopped() bool {
return bm.hasStopped
}
// TopRunner 开始运行一个模块
func (bm *BaseModule) TopRunner() {
bm.TimerManager.RegTimer(time.Minute, 0, false, func(t time.Duration) bool {
bm.Syslog("[BaseModule] Timer 1 minute...")
return true
})
}
func (bm *BaseModule) watchLoadToLog(dt time.Duration) bool {
load := bm.load.GetLoad()
incValue := load - bm.lastCheckLoad
if incValue > 0 {
bm.Info("[BaseModule] watchLoadToLog within n sec load", log.Float64("Sec", dt.Seconds()), log.Int64("Load", incValue))
}
bm.lastCheckLoad = load
return true
}