使用go官方的http.request + context样例

go >= 1.7 中官方的http.request中已经支持了context,使用context编写代码控制超时和关闭非常方便,当然代码也更加优雅,代码如下:

Github Addr

package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "time"
)

func HttpDoTest(ctx context.Context, resChan chan<- string) error {
    start := time.Now()

    repoUrl := "https://api.github.com/repos/campoy/golang-plugins"
    req, err := http.NewRequest("GET", repoUrl, nil)
    if err != nil {
        return fmt.Errorf("http.NewRequest Error: %s", err.Error())
    }

    // in go >= 1.7
    req = req.WithContext(ctx)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return fmt.Errorf("client.Do Error: %s", err.Error())
    }

    data, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return fmt.Errorf("ioutil.ReadAll Error: %s", err.Error())
    }

    log.Printf("Read body size [%d]", len(data))
    log.Println("CostTime is: " + time.Since(start).String())

    resChan <- string(data)

    return nil
}

func main() {
    deadline := 1
    d := time.Now().Add(time.Duration(deadline) * time.Second) // deadline max
    ctx, cancel := context.WithDeadline(context.Background(), d)
    defer cancel()

    resChan := make(chan string)

    go HttpDoTest(ctx, resChan)

    var resData string
    select {
    case <-ctx.Done():
        fmt.Println(ctx.Err())

        /* just for ex use. No used*/
    case <-time.Tick(time.Duration(time.Duration(deadline*2) * time.Second)):
        fmt.Println("Time over!")

    case resData = <-resChan:
        fmt.Println("Read data finished")
    }

    log.Printf("Read data size: [%d]", len(resData))
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注