Skip to content

Instantly share code, notes, and snippets.

@s-shin
Last active April 11, 2017 17:04
Show Gist options
  • Save s-shin/a777061997631301c10e7a3a988be7f4 to your computer and use it in GitHub Desktop.
Save s-shin/a777061997631301c10e7a3a988be7f4 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"os"
"strconv"
"time"
)
type Foo struct {
Foo int `json:"foo"`
}
func main() {
if len(os.Args) != 3 {
fmt.Printf("Usage: %s <sever-sleep-sec> <request-timeout-sec>\n", os.Args[0])
return
}
sleepSec, err := strconv.Atoi(os.Args[1])
if err != nil {
log.Fatalf("[main] %s", err)
}
timeoutSec, err := strconv.Atoi(os.Args[2])
if err != nil {
log.Fatalf("[main] %s", err)
}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for i := 1; i <= sleepSec; i++ {
log.Printf("[server] %d", i)
time.Sleep(1 * time.Second)
}
w.Write([]byte(`{"foo": 100}`))
}))
defer ts.Close()
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSec)*time.Second)
defer cancel()
errCh := make(chan error, 1)
resultCh := make(chan *Foo, 1)
go func() {
req, err := http.NewRequest(http.MethodGet, ts.URL, nil)
if err != nil {
errCh <- err
return
}
req.WithContext(ctx)
res, err := http.DefaultClient.Do(req)
if err != nil {
errCh <- err
return
}
data, err := ioutil.ReadAll(res.Body)
if err != nil {
errCh <- err
return
}
var foo Foo
if err := json.Unmarshal(data, &foo); err != nil {
errCh <- err
return
}
resultCh <- &foo
}()
select {
case result := <-resultCh:
fmt.Printf("[main] Foo: %d\n", result.Foo)
case err := <-errCh:
fmt.Printf("[main] error: %s\n", err)
case <-ctx.Done():
fmt.Printf("[main] error: %s\n", ctx.Err())
}
// NOTE: looks not to be suspended. (because of httptest???)
time.Sleep(2 * time.Second)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment