File tree Expand file tree Collapse file tree 1 file changed +55
-0
lines changed Expand file tree Collapse file tree 1 file changed +55
-0
lines changed Original file line number Diff line number Diff line change
1
+ package middleware
2
+
3
+ import (
4
+ "context"
5
+ "github.com/gin-gonic/gin"
6
+ "net/http"
7
+ "time"
8
+ )
9
+
10
+ // TimeoutMiddleware 创建超时中间件
11
+ // 入参 timeout 设置超时时间(例如:time.Second * 5)
12
+ // 使用示例 xxx.Get("path",middleware.TimeoutMiddleware(30*time.Second),HandleFunc)
13
+ func TimeoutMiddleware (timeout time.Duration ) gin.HandlerFunc {
14
+ return func (c * gin.Context ) {
15
+ ctx , cancel := context .WithTimeout (c .Request .Context (), timeout )
16
+ defer cancel ()
17
+
18
+ c .Request = c .Request .WithContext (ctx )
19
+
20
+ // 使用 buffered channel 避免 goroutine 泄漏
21
+ done := make (chan struct {}, 1 )
22
+ panicChan := make (chan interface {}, 1 )
23
+
24
+ go func () {
25
+ defer func () {
26
+ if p := recover (); p != nil {
27
+ select {
28
+ case panicChan <- p :
29
+ default :
30
+ }
31
+ }
32
+ select {
33
+ case done <- struct {}{}:
34
+ default :
35
+ }
36
+ }()
37
+ c .Next ()
38
+ }()
39
+
40
+ select {
41
+ case p := <- panicChan :
42
+ panic (p )
43
+ case <- done :
44
+ return
45
+ case <- ctx .Done ():
46
+ // 确保服务器超时设置足够长
47
+ c .Header ("Connection" , "close" )
48
+ c .AbortWithStatusJSON (http .StatusGatewayTimeout , gin.H {
49
+ "code" : 504 ,
50
+ "msg" : "请求超时" ,
51
+ })
52
+ return
53
+ }
54
+ }
55
+ }
You can’t perform that action at this time.
0 commit comments