Skip to content

Commit d50c0fd

Browse files
committed
增加Graceful关闭机制
1 parent 4a08853 commit d50c0fd

9 files changed

+122
-56
lines changed

.idea/echox.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

echo.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type Echo struct {
1919
}
2020

2121
func New(opts ...option) *Echo {
22-
options := defaultOptions()
22+
options := defaultOptions
2323
for _, opt := range opts {
2424
opt.apply(options)
2525
}
@@ -96,17 +96,41 @@ func (e *Echo) Start(opts ...startOption) (err error) {
9696
}
9797

9898
// 在另外的协程中启动服务器,实现优雅地关闭(Graceful Shutdown)
99-
go func() {
99+
if options.graceful {
100+
go func() {
101+
err = e.graceful(options)
102+
}()
103+
} else {
100104
err = e.Echo.Start(e.options.addr)
101-
}()
105+
}
106+
107+
return
108+
}
109+
110+
func (e *Echo) Stop(opts ...stopOption) error {
111+
options := defaultStopOptions()
112+
for _, opt := range opts {
113+
opt.applyStop(options)
114+
}
115+
116+
ctx, cancel := context.WithTimeout(context.Background(), options.timeout)
117+
defer cancel()
118+
119+
return e.Echo.Shutdown(ctx)
120+
}
121+
122+
func (e *Echo) graceful(options *startOptions) (err error) {
123+
if err = e.Echo.Start(e.options.addr); nil != err {
124+
return
125+
}
102126

103127
// 等待系统退出中断并响应
104128
quit := make(chan os.Signal)
105129
signal.Notify(quit, os.Interrupt)
106130
<-quit
107131
ctx, cancel := context.WithTimeout(context.Background(), options.shutdownTimeout)
108132
defer cancel()
109-
err = e.Shutdown(ctx)
133+
err = e.Echo.Shutdown(ctx)
110134

111135
return
112136
}

option_shutdown_timeout.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package echox
2+
3+
import (
4+
`time`
5+
)
6+
7+
var (
8+
_ startOption = (*optionShutdownTimeout)(nil)
9+
_ stopOption = (*optionShutdownTimeout)(nil)
10+
)
11+
12+
type optionShutdownTimeout struct {
13+
timeout time.Duration
14+
}
15+
16+
// ShutdownTimeout 配置退出超时时间
17+
func ShutdownTimeout(timeout time.Duration) *optionShutdownTimeout {
18+
return &optionShutdownTimeout{
19+
timeout: timeout,
20+
}
21+
}
22+
23+
func (st *optionShutdownTimeout) applyStart(options *startOptions) {
24+
options.shutdownTimeout = st.timeout
25+
}
26+
27+
func (st *optionShutdownTimeout) applyStop(options *stopOptions) {
28+
options.timeout = st.timeout
29+
}

options.go

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
package echox
22

3-
import (
4-
`time`
5-
)
3+
var defaultOptions = &options{
4+
addr: ":9000",
5+
binder: true,
6+
validate: true,
7+
banner: false,
8+
error: errorHandlerFunc,
9+
crosEnable: true,
10+
cros: crosConfig{
11+
origins: []string{"*"},
12+
credentials: true,
13+
},
14+
panicStack: panicStackConfig{
15+
size: 4 << 10,
16+
disableStackAll: false,
17+
disablePrintStack: false,
18+
},
19+
}
620

721
type options struct {
822
// 地址
@@ -19,8 +33,7 @@ type options struct {
1933
inits []initFunc
2034
// 错误处理
2135
error errorHandler
22-
// 退出超时时间
23-
shutdownTimeout time.Duration
36+
2437
// 跨域
2538
crosEnable bool
2639
cros crosConfig
@@ -29,24 +42,3 @@ type options struct {
2942
// 打印堆栈信息
3043
panicStack panicStackConfig
3144
}
32-
33-
func defaultOptions() *options {
34-
return &options{
35-
addr: ":9000",
36-
binder: true,
37-
validate: true,
38-
banner: false,
39-
error: errorHandlerFunc,
40-
shutdownTimeout: 30 * time.Second,
41-
crosEnable: true,
42-
cros: crosConfig{
43-
origins: []string{"*"},
44-
credentials: true,
45-
},
46-
panicStack: panicStackConfig{
47-
size: 4 << 10,
48-
disableStackAll: false,
49-
disablePrintStack: false,
50-
},
51-
}
52-
}

start_option_graceful.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package echox
2+
3+
var _ startOption = (*startOptionGraceful)(nil)
4+
5+
type startOptionGraceful struct{}
6+
7+
// Graceful 配置Graceful退出机制
8+
func Graceful() *startOptionGraceful {
9+
return &startOptionGraceful{}
10+
}
11+
12+
func (g *startOptionGraceful) applyStart(startOptions *startOptions) {
13+
startOptions.graceful = true
14+
}

start_option_shutdown_timeout.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

start_options.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ import (
55
)
66

77
type startOptions struct {
8-
// 退出超时时间
8+
*options
9+
10+
graceful bool
911
shutdownTimeout time.Duration
10-
// 初始化路由方法
11-
routes []routeFunc
12+
routes []routeFunc
1213
}
1314

1415
func defaultStartOptions() *startOptions {
1516
return &startOptions{
17+
options: defaultOptions,
18+
19+
graceful: false,
1620
shutdownTimeout: 30 * time.Second,
1721
routes: []routeFunc{func(group *Group) {
1822
group.Get("/routes", routeHandler).Name = "所有路由信息"

stop_option.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package echox
2+
3+
type stopOption interface {
4+
applyStop(options *stopOptions)
5+
}

stop_options.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package echox
2+
3+
import (
4+
`time`
5+
)
6+
7+
type stopOptions struct {
8+
*options
9+
10+
// 退出超时时间
11+
timeout time.Duration
12+
}
13+
14+
func defaultStopOptions() *stopOptions {
15+
return &stopOptions{
16+
options: defaultOptions,
17+
18+
timeout: 30 * time.Second,
19+
}
20+
}

0 commit comments

Comments
 (0)