go - How to handle HTTP timeout errors and accessing status codes in golang -
i have code (see below) written in go supposed "fan-out" http requests, , collate/aggregate details back.
i'm new golang , expect me noob , knowledge limited
the output of program like:
{ "status":"success", "components":[ {"id":"foo","status":200,"body":"..."}, {"id":"bar","status":200,"body":"..."}, {"id":"baz","status":404,"body":"..."}, ... ] }
there local server running purposely slow (sleeps 5 seconds , returns response). have other sites listed (see code below) sometime trigger error (if error, that's fine).
the problem have @ moment how best handle these errors, , "timeout" related errors; in i'm not sure how recognise if failure timeout or other error?
at moment blanket error time:
get http://localhost:8080/pugs: read tcp 127.0.0.1:8080: use of closed network connection
where http://localhost:8080/pugs
url failed (hopefully timeout!). can see code (below), i'm not sure how determine error code related timeout nor how access status code of response (i'm blanket setting 404
that's not right - if server error i'd expect 500
status code , i'd reflect in aggregated response send back).
the full code can seen below. appreciated.
package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "sync" "time" ) type component struct { id string `json:"id"` url string `json:"url"` } type componentslist struct { components []component `json:"components"` } type componentresponse struct { id string status int body string } type result struct { status string components []componentresponse } var overallstatus string = "success" func main() { var cr []componentresponse var c componentslist b := []byte(`{"components":[{"id":"local","url":"http://localhost:8080/pugs"},{"id":"google","url":"http://google.com/"},{"id":"integralist","url":"http://integralist.co.uk/"},{"id":"sloooow","url":"http://stevesouders.com/cuzillion/?c0=hj1hfff30_5_f&t=1439194716962"}]}`) json.unmarshal(b, &c) var wg sync.waitgroup timeout := time.duration(1 * time.second) client := http.client{ timeout: timeout, } i, v := range c.components { wg.add(1) go func(i int, v component) { defer wg.done() resp, err := client.get(v.url) if err != nil { fmt.printf("problem getting response: %s\n", err) cr = append(cr, componentresponse{ v.id, 404, err.error(), }) } else { defer resp.body.close() contents, err := ioutil.readall(resp.body) if err != nil { fmt.printf("problem reading body: %s\n", err) } cr = append(cr, componentresponse{ v.id, resp.statuscode, string(contents), }) } }(i, v) } wg.wait() j, err := json.marshal(result{overallstatus, cr}) if err != nil { fmt.printf("problem converting json: %s\n", err) return } fmt.println(string(j)) }
if want fan out aggregate results , want specific timeout behavior net/http package isn't giving you, may want use goroutines , channels.
i watched video today , walk through scenarios using concurrency features of go. plus, speaker rob pike quite authority -- explains better could.
Comments
Post a Comment