Gin增加超时控制中间件

Gin增加超时控制

背景

  • 有时候很多API有业务超时要求,就是数据必须在几秒内返回,超时的话立刻结束,不用卡死在某一个页面上。

目标

  • 对这一类API特定处理,增加超时控制,不要影响别的API

方案

  • 方案很简单,就是利用go提供的context技术对gin框架的request对象进行改造,使其具备超时控制机能。

代码:

package main

import (
 "context"
 "fmt"
 "log"
 "net/http"
 "time"

 "github.com/gin-gonic/gin"
)

// 超时控制中间件
func timeoutMiddleware(timeout time.Duration) func(c *gin.Context) {
 return func(c *gin.Context) {
  // 用超时context wrap request的context
  ctx, cancel := context.WithTimeout(c.Request.Context(), timeout)

  defer func() {
   // 检查是否超时
   if ctx.Err() == context.DeadlineExceeded {
    c.Writer.WriteHeader(http.StatusGatewayTimeout)
    c.Abort()
   }

   //清理资源
   cancel()
  }()

  // 替换
  c.Request = c.Request.WithContext(ctx)
  c.Next()
 }
}

func timedHandler(duration time.Duration) func(c *gin.Context) {
 return func(c *gin.Context) {
  // 获取替换之后的context 它具备了超时控制
  ctx := c.Request.Context()

  // 定义响应struct
  type responseData struct {
   status int
   body   map[string]interface{}
  }

  // 创建一个done chan表明request要完成了
  doneChan := make(chan responseData)
  // 模拟API耗时的处理
  go func() {
   time.Sleep(duration)
   doneChan <- responseData{
    status: 200,
    body:   gin.H{"hello""world"},
   }
  }()

  // 监听两个chan谁先到达
  select {

  // 超时
  case <-ctx.Done():
   return

   // 请求完成
  case res := <-doneChan:
   c.JSON(res.status, res.body)
  }
 }
}

func main() {
 engine := gin.New()

 // 不用超时控制
 group := engine.Group("/normal")
 {
  group.GET("/short", timedHandler(time.Second))
 }

 // 需要超时控制 时间控制在2s
 timeoutGroup := engine.Group("/timeout")
 timeoutGroup.Use(timeoutMiddleware(time.Second * 2))
 {
  // 延迟5s
  timeoutGroup.GET("/long", timedHandler(time.Second*5))
 }

 // run the server
 log.Fatal(engine.Run(":5090"))
}

验证

  1. 正常请求Gin增加超时控制中间件
  2. 超时请求Gin增加超时控制中间件


原文始发于微信公众号(堆栈future):Gin增加超时控制中间件

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/103464.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!