29
golang http server如何设置request的context超时
source link: https://studygolang.com/articles/31361
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
main函数
func main() { address := fmt.Sprintf("%s:%d", "0.0.0.0", 8080) router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/api/hello", handler) err := http.ListenAndServe(address, router) if err != nil { log.Panic("ListenAndServe err:", err) } }
handler函数
func handler(w http.ResponseWriter, r *http.Request) { log.Printf("Request is coming\n") var userId string if queryParams, ok := r.URL.Query()["user"]; ok && len(queryParams) > 0 { userId = queryParams[0] } // handle context timeout var ctx context.Context var cancel context.CancelFunc if queryParams, ok := r.URL.Query()["timeout"]; ok && len(queryParams) > 0 { timeout, err := time.ParseDuration(queryParams[0]) if err != nil { ctx, cancel = context.WithCancel(r.Context()) } else { ctx, cancel = context.WithTimeout(r.Context(), timeout) } } else { ctx, cancel = context.WithCancel(r.Context()) } defer cancel() // call implementation function result, err := GetUser(ctx, userId) if err != nil { log.Printf("Request is return with error: %v\n", err) writeErrorResponse(http.StatusInternalServerError, err, w) return } log.Printf("Request is return with success\n") writeResponse(http.StatusOK, result, w) }
在handler函数里面从r.Context生成一个新的context,并传递给功能函数GetUser(ctx context).
功能函数
func GetUser(ctx context.Context, userId string) (map[string]string, error) { c := make(chan interface{}, 1) go func() { time.Sleep(10 * time.Second) c <- "123-456-7890" } () select { case <-ctx.Done(): log.Printf("Context interrupt or timeout: %v\n", ctx.Err()) return nil, fmt.Errorf("Context interrupt or timeout: %v", ctx.Err()) case result := <-c: return map[string]string{"name":userId, "phone": result.(string)}, nil } }
在功能函数里面,异步方式调用起来具体的实现功能,然后等待在ctx.Done()或者c里面有数据。
- ctx.Done返回如果满足:
-- client放弃请求,或者
-- 超时,根据参数timeout设置的超时 - c里面有数据,则表示具体的实现功能函数完成,在这里例子里是匿名函数执行返回。
使用curl工具发起client请求:
- curl localhost:8080/api/hello
正常请求,10秒后返回 - curl localhost:8080/api/hello + ctrl-C
用户ctrl-C杀掉curl命令 - curl --max-time 5 localhost:8080/api/hello
客户端设置5秒超时
有疑问加站长微信联系
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK