package my_context import ( "context" "fmt" "net/http" ) type Store interface { Fetch(ctx context.Context) (string, error) // instead of calling cancel we want to use context above to cross API boundries // Cancel() } func Server(store Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // THIS WAS WHAT WE DID WHEN WE DIDN"T PROPOGATE CONTEXT // // This is the requests ctx not a derived context // ctx := r.Context() // data := make(chan string, 1) // go func() { // data <- store.Fetch() // }() // // Here we are simply waiting on the which channel // // will close out first. If the Done() channel on the request // // does store.Cancel() is called. // // Remember select lets use wait on multiple async operations and execute cases // // based on which one completes first as signaled by data being received on that channel. // select { // case d := <-data: // fmt.Fprint(w, d) // case <-ctx.Done(): // store.Cancel() // } data, err := store.Fetch(r.Context()) if err != nil { return // todo log the error however you like } fmt.Fprint(w, data) } }