-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathengine.go
More file actions
171 lines (147 loc) · 3.81 KB
/
engine.go
File metadata and controls
171 lines (147 loc) · 3.81 KB
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
package nano
import (
"errors"
"net/http"
"os"
"os/signal"
"strings"
"sync/atomic"
"syscall"
"github.com/lonng/nano/cluster"
"github.com/lonng/nano/component"
"github.com/lonng/nano/internal/utils/assert"
"github.com/lonng/nano/npi"
"github.com/lonng/nano/scheduler"
)
// VERSION returns current nano version
var VERSION = "0.5.0"
var _ npi.Engine = (*Engine)(nil)
// Engine 引擎
type Engine struct {
npi.RouterGroup
trees npi.HandlerTrees
allNoRoute npi.HandlersChain
noRoute npi.HandlersChain
running atomic.Bool
node *cluster.Node
opts *cluster.Options
}
// New 创建引擎实例
func New(opts ...Option) *Engine {
options := cluster.DefaultOptions()
for _, opt := range opts {
opt(options)
}
engine := &Engine{
trees: npi.HandlerTrees{},
allNoRoute: nil,
noRoute: nil,
opts: options,
}
engine.RouterGroup = npi.NewRootGroup(engine)
return engine
}
// ServeHTTP conforms to the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
engine.node.ServeHTTP(w, r)
}
// NoRoute 为 NoRoute 添加处理程序。默认情况下,它返回一个 404 代码。
func (engine *Engine) NoRoute(handlers ...npi.HandlerFunc) {
engine.noRoute = handlers
engine.rebuild404Handlers()
}
// rebuild404Handlers 重新组织 404 处理程序
func (engine *Engine) rebuild404Handlers() {
engine.allNoRoute = engine.CombineHandlers(engine.noRoute)
}
// AddRoute 添加路由
func (engine *Engine) AddRoute(path string, handlers ...npi.HandlerFunc) {
assert.Assert(strings.Contains(path, "."), "path should contains '.'")
assert.Assert(len(handlers) > 0, "there must be at least one handler")
engine.trees.Append(path, npi.NewHandlerNode(handlers...))
}
// Routes 获取注册的路由信息
func (engine *Engine) Routes() npi.RoutesInfo {
var routes npi.RoutesInfo
for path, node := range engine.trees {
routes = append(routes, npi.RouteInfo{
Path: path,
Handler: node.Name(),
HandlerFunc: node.Handlers().Last(),
})
}
return routes
}
// Trees 获取全部路由处理程序
func (engine *Engine) Trees() npi.HandlerTrees {
return engine.trees
}
// AllNoRoutes 获取无路由的处理程序
func (engine *Engine) AllNoRoutes() npi.HandlersChain {
return engine.allNoRoute
}
// Register 注册组件
func (engine *Engine) Register(component component.Component, options ...component.Option) {
engine.opts.Components.Register(component, options...)
}
// SessionCount 获取当前会话数量
func (engine *Engine) SessionCount() int {
node := engine.node
if node == nil {
return 0
}
return node.SessionCount()
}
// Startup 启动引擎
func (engine *Engine) Startup() error {
if !engine.running.CompareAndSwap(false, true) {
return errors.New("nano has running")
}
scheduler.Start()
engine.node = cluster.NewNode(engine, engine.opts)
return nil
}
// Shutdown 发送信号并关闭 nano
func (engine *Engine) Shutdown() {
if !engine.running.CompareAndSwap(true, false) {
return
}
if engine.node != nil {
engine.node.Shutdown()
}
scheduler.Close()
}
// RunTcp 启动 TCP 服务
func (engine *Engine) RunTcp(addr string) error {
err := engine.Startup()
if err != nil {
return err
}
return engine.node.ListenAndServe(addr)
}
// RunWs 启动 WebSocket 服务
func (engine *Engine) RunWs(addr string, path string) error {
err := engine.Startup()
if err != nil {
return err
}
return engine.node.ListenAndServeWs(addr, path)
}
// Run 启动 grpc 服务, 并等待退出信号
func (engine *Engine) Run() error {
err := engine.Startup()
if err != nil {
return err
}
engine.Wait()
return nil
}
// Wait 等待退出信号
func (engine *Engine) Wait() {
sg := make(chan os.Signal)
signal.Notify(sg, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM)
select {
case <-sg:
}
engine.Shutdown()
}