【问题标题】:go-gin request cancellationgo-gin 请求取消
【发布时间】:2020-07-05 22:17:19
【问题描述】:

如果连接在 10 秒前关闭,如何取消进一步处理?

c.Request.Context().Done(),但找不到使用示例。

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        time.Sleep(10 * time.Second) // or some db operation
        log.Print("Processing")
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run()
}

【问题讨论】:

    标签: go go-gin


    【解决方案1】:

    您可以异步运行长时间运行的操作,并让它在通道上发送以发出完成信号。

    然后你用select 语句阻塞该完成通道和c.Request.Context().Done()

    func main() {
        r := gin.Default()
        r.GET("/ping", func(c *gin.Context) {
            signal := make(chan struct{}, 1)
    
            go longRunningOperation(signal)
    
            select {
                case <-signal:
                    close(signal) // remember to clean up after yourself
                    // move on, will print "Processing"
        
                case <-c.Request.Context().Done():
                    // abort
                    return
            }
    
            log.Print("Processing")
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })
        r.Run()
    }
    
    
    func longRunningOperation(signal chan<- struct{}) {
        time.Sleep(10 * time.Second)
        signal <- struct{}{} // signal that this operation has finished
    }
    

    这种方法的缺点是,原样,长时间运行的操作本身会继续执行。

    当你的程序的 main 函数返回时,Goroutines 退出,而实际的 gin 服务器并非如此。所以这可能不是你想要的。

    在数据库操作的情况下,大多数API都需要一个context.Context参数,可以用来检测请求取消。因此,您可以将c.Request.Context() 传递到调用链中,以确保异步长时间运行的操作在客户端断开连接时也终止。

    func Handler(c *gin.Context) {
        signal := make(chan struct{}, 1)
        go longRunningOperation(c.Request.Context(), signal)
        ...
    }
    
    func longRunningOperation(ctx context.Context, signal chan<- struct{}) {
        if err := doSomethingContext(ctx); err != nil {
            return
        }
        signal <- struct{}{} // signal that this operation has finished (successfully)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-25
      • 1970-01-01
      • 2021-11-06
      • 2017-07-04
      • 1970-01-01
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多