| 13 | ) |
| 14 | |
| 15 | func hello(w http.ResponseWriter, req *http.Request) { |
| 16 | |
| 17 | // A `context.Context` is created for each request by |
| 18 | // the `net/http` machinery, and is available with |
| 19 | // the `Context()` method. |
| 20 | ctx := req.Context() |
| 21 | fmt.Println("server: hello handler started") |
| 22 | defer fmt.Println("server: hello handler ended") |
| 23 | |
| 24 | // Wait for a few seconds before sending a reply to the |
| 25 | // client. This could simulate some work the server is |
| 26 | // doing. While working, keep an eye on the context's |
| 27 | // `Done()` channel for a signal that we should cancel |
| 28 | // the work and return as soon as possible. |
| 29 | select { |
| 30 | case <-time.After(10 * time.Second): |
| 31 | fmt.Fprintf(w, "hello\n") |
| 32 | case <-ctx.Done(): |
| 33 | // The context's `Err()` method returns an error |
| 34 | // that explains why the `Done()` channel was |
| 35 | // closed. |
| 36 | err := ctx.Err() |
| 37 | fmt.Println("server:", err) |
| 38 | internalError := http.StatusInternalServerError |
| 39 | http.Error(w, err.Error(), internalError) |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | func main() { |
| 44 | |