dongyan7988 2017-07-07 20:26
浏览 194

如何在嵌套的HTTP中间件中使用context.Done()

I would like to know how to properly implement/use context.Done() method when using it within an HTTP server and implementing middleware, my goal is to cancel subsequent events when a client disconnects across nested middleware.

For testing I created the following code, I don't know if is the correct way of doing it since I had to create a channel within the HandleFunc and a goroutine to handle the requests, putting all this together within a select wait statement.

package main

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

func hello(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    log.Println("handler started")
    defer log.Println("hander ended")

    ch := make(chan struct{})

    go func() {
        time.Sleep(5 * time.Second)
        fmt.Fprintln(w, "Hello")
        ch <- struct{}{}
    }()

    select {
    case <-ch:
    case <-ctx.Done():
        err := ctx.Err()
        log.Println(err)
        http.Error(w, err.Error(), http.StatusPartialContent)
    }
}

func main() {
    http.HandleFunc("/", hello)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Basically here the request simulates load by sleeping 5 seconds, and then prints Hello, but if the client cancels the request, for example:

$ curl 0:8080

And then pressing <kbd>ctl</kbd> + <kbd> c</kbd>, this will be loged:

2017/07/07 22:22:40 handler started
2017/07/07 22:22:42 context canceled
2017/07/07 22:22:42 hander ended

This works but wondering if this pattern (the goroutine and select) should be used in every nested handler or if there is a better way of implementing this.:

ch := make(chan struct{})
go func() {
    // some logic   
    ch <- struct{}{}
}()

select {
case <-ch:
case <-ctx.Done():
    err := ctx.Err()
    log.Println(err)
    http.Error(w, err.Error(), http.StatusPartialContent)
}
  • 写回答

1条回答 默认 最新

  • doupo1908 2017-07-09 02:40
    关注

    At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests.

    -- Go Concurrency Patterns: Context

    评论

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。