设置内置的HTTP请求超时的最佳方法是什么?

huangapple go评论192阅读模式
英文:

The best way to set the timeout on built-in HTTP request

问题

设置内置http.NewRequest的超时时间的最佳方法是什么?目前,我正在使用http.Client的Timeout属性,它覆盖整个请求过程,但是否有更好的方法,例如使用context.WithDeadlinecontext.WithTimeout?如果有,它是如何工作的?如何为http.NewRequest设置context.WithDeadline解决方案?

以下是我目前的解决方案:

  1. func (c *Client) post(resource string, data url.Values, timeout time.Duration) ([]byte, error) {
  2. url := c.getURL(resource)
  3. client := &http.Client{
  4. Timeout: timeout * time.Millisecond,
  5. }
  6. req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
  7. if err != nil {
  8. return nil, err
  9. }
  10. req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  11. resp, err := client.Do(req)
  12. if err != nil {
  13. return nil, err
  14. }
  15. return ioutil.ReadAll(resp.Body)
  16. }

请注意,这是一个示例代码,你可以根据自己的需求进行调整。

英文:

What is the best way to setup a timeout on built-in http NewRequest? Currently, I'm using http.Client.Timeout which is cover the entire exchange, but is there something better for example context.WithDeadline or context.WithTimeout. If yes how is it working, how can I setup a context.WithDeadline solution for the http.NewRequest?

There is my current solution:

  1. func (c *Client) post(resource string, data url.Values, timeout time.Duration) ([]byte, error) {
  2. url := c.getURL(resource)
  3. client := &http.Client{
  4. Timeout: timeout * time.Millisecond,
  5. }
  6. req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
  7. if err != nil {
  8. return nil, err
  9. }
  10. req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  11. resp, err := client.Do(req)
  12. if err != nil {
  13. return nil, err
  14. }
  15. return ioutil.ReadAll(resp.Body)
  16. }

答案1

得分: 1

从context.WithDeadline中获取新的上下文。请参阅文档
WithTimeout只是返回WithDeadline(parent, time.Now().Add(timeout))。

  1. package main
  2. import (
  3. "context"
  4. "io"
  5. "log"
  6. "net/http"
  7. "os"
  8. "time"
  9. )
  10. func getContent(ctx context.Context) {
  11. req, err := http.NewRequest("GET", "http://example.com", nil)
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. ctx, cancel := context.WithDeadline(ctx, time.Now().Add(3 * time.Second))
  16. defer cancel()
  17. req.WithContext(ctx)
  18. resp, err := http.DefaultClient.Do(req)
  19. if err != nil {
  20. log.Fatal(err)
  21. }
  22. defer resp.Body.Close()
  23. io.Copy(os.Stdout, resp.Body)
  24. }
  25. func main() {
  26. ctx := context.Background()
  27. getContent(ctx)
  28. }

如果你想在main函数中触发取消操作:

  1. func main() {
  2. ctx := context.Background()
  3. ctx, cancel := context.WithCancel(ctx)
  4. sc := make(chan os.Signal, 1)
  5. signal.Notify(sc, os.Interrupt)
  6. go func(){
  7. <-sc
  8. cancel()
  9. }()
  10. getContent(ctx)
  11. }
英文:

Get new context from context.WithDeadline. See documentation.
WithTimeout just returns WithDeadline(parent, time.Now().Add(timeout)).

  1. package main
  2. import (
  3. &quot;context&quot;
  4. &quot;io&quot;
  5. &quot;log&quot;
  6. &quot;net/http&quot;
  7. &quot;os&quot;
  8. &quot;time&quot;
  9. )
  10. func getContent(ctx context.Context) {
  11. req, err := http.NewRequest(&quot;GET&quot;, &quot;http://example.com&quot;, nil)
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. ctx, cancel := context.WithDeadline(ctx, time.Now().Add(3 * time.Second))
  16. defer cancel()
  17. req.WithContext(ctx)
  18. resp, err := http.DefaultClient.Do(req)
  19. if err != nil {
  20. log.Fatal(err)
  21. }
  22. defer resp.Body.Close()
  23. io.Copy(os.Stdout, resp.Body)
  24. }
  25. func main() {
  26. ctx := context.Background()
  27. getContent(ctx)
  28. }

If you want to make cancel trigger on main:

  1. func main() {
  2. ctx := context.Background()
  3. ctx, cancel := context.WithCancel(ctx)
  4. sc := make(chan os.Signal, 1)
  5. signal.Notify(sc, os.Interrupt)
  6. go func(){
  7. &lt;-sc
  8. cancel()
  9. }()
  10. getContent(ctx)
  11. }

huangapple
  • 本文由 发表于 2017年7月5日 01:49:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/44911726.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定