/
engine.go
164 lines (140 loc) · 2.97 KB
/
engine.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
package cola
import (
"fmt"
"os"
"os/signal"
"sort"
"strings"
"sync"
"syscall"
)
// Engine Module engine
type Engine struct {
core *Core
quit chan os.Signal
}
var (
modules = make(map[string]ModuleInfo)
modulesMu sync.RWMutex
modexit = make([]hasExit, 0)
)
// Module interface
type Module interface {
Module() ModuleInfo
}
// ModuleInfo ModuleInfo
type ModuleInfo struct {
ID string
New func() Module
}
type hasHand interface {
Preload(*Ctx)
}
type hasHook interface {
LastHook(*Ctx)
}
type hasStart interface {
Start(*Engine)
}
type hasExit interface {
Exit()
}
// NewEngine 创建
func NewEngine(opts ...interface{}) *Engine {
engine := &Engine{
core: New(opts...),
quit: make(chan os.Signal, 1),
}
signal.Notify(engine.quit, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGUSR2)
go engine.looper()
return engine
}
// Core 返回 core对象
func (e *Engine) Core() *Core {
return e.core
}
// Serve 启动服务 如果modules 定义 prefix 为 module. 这里则加载
func (e *Engine) Serve(port interface{}) error {
defer e.Exit()
for _, m := range GetModules("module") {
mo := m.New()
if mod, ok := mo.(hasExit); ok {
modexit = append(modexit, mod)
}
if mod, ok := mo.(hasStart); ok { // 独立启动程序, 那就启动
mod.Start(e)
}
if mod, ok := mo.(hasHand); ok { // 如果这个模块是handler 注册这个模块
e.core.Use(mod)
}
if hook, ok := mo.(hasHook); ok { // 拥有全局Hook
e.core.Use(hook.LastHook)
}
}
return e.core.Serve(port)
}
func (e *Engine) looper() {
for {
select {
case <-e.quit:
e.core.Server.Shutdown()
}
}
}
func (e *Engine) Exit() {
for _, m := range modexit {
m.Exit()
}
}
// RegisterModule 注册模块
func RegisterModule(inst Module) {
mod := inst.Module()
modulesMu.Lock()
defer modulesMu.Unlock()
if _, ok := modules[string(mod.ID)]; ok {
Log.Info("module already registered: %s\n", mod.ID)
return
}
modules[mod.ID] = mod
}
// GetModule 通过ID获得模块
//
// 获得后自己定义接口再调用某方法
func GetModule(name string) (ModuleInfo, error) {
modulesMu.RLock()
defer modulesMu.RUnlock()
m, ok := modules[name]
if !ok {
return ModuleInfo{}, fmt.Errorf("module not register: %s", name)
}
return m, nil
}
// GetModules 获取指定开头的模块
func GetModules(scope string) []ModuleInfo {
modulesMu.RLock()
defer modulesMu.RUnlock()
scopeParts := strings.Split(scope, ".")
if scope == "" {
scopeParts = []string{}
}
mods := make([]ModuleInfo, 0)
iterateModules:
for id, m := range modules {
modParts := strings.Split(id, ".")
// match only the next level of nesting
if len(modParts) < len(scopeParts) {
continue
}
// specified parts must be exact matches
for i := range scopeParts {
if modParts[i] != scopeParts[i] {
continue iterateModules
}
}
mods = append(mods, m)
}
sort.Slice(mods, func(i, j int) bool {
return mods[i].ID < mods[j].ID
})
return mods
}