Skip to content

Instantly share code, notes, and snippets.

@vigliag
Forked from perillo/try-http-ctx-cancellation.go
Last active January 7, 2020 15:32
Show Gist options
  • Save vigliag/92046915cb0c3377464b9841a9216aa7 to your computer and use it in GitHub Desktop.
Save vigliag/92046915cb0c3377464b9841a9216aa7 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"log"
"net/http"
"time"
)
func newReader(delay time.Duration) io.Reader {
r, w := io.Pipe()
go func() {
for {
n, err := w.Write([]byte("x\n"))
if err != nil {
log.Printf("writing request body: %v", n)
continue
}
fmt.Printf("wrote %d bytes to request body\n", n)
time.Sleep(delay)
}
w.Close()
}()
return r
}
func client(addr string, delay time.Duration) error {
addr = "http://" + addr // make a correct URL from a IP address
body := newReader(delay)
fmt.Println("starting client")
res, err := http.Post(addr, "text/plain", body)
if err != nil {
log.Fatal(err)
}
log.Println(res)
return err
}
func server(addr string, handler http.HandlerFunc, timeout time.Duration) error {
srv := http.Server{
Addr: addr,
Handler: handler,
ReadTimeout: timeout,
}
fmt.Println("starting server")
return srv.ListenAndServe()
}
func handler(w http.ResponseWriter, req *http.Request) {
buf := make([]byte, 2)
ctx := req.Context()
// A simple concurrent worker.
for {
select {
case <-ctx.Done():
log.Printf("cancelling job")
return
default:
n, err := req.Body.Read(buf)
if err != nil {
log.Printf("reading request body: %v", err)
continue // give ctx.Done a chance
}
fmt.Printf("read %d bytes from request body\n", n)
}
}
}
func main() {
const (
addr = "127.0.0.1:8080"
delay = time.Second
timeout = 3 * time.Second
)
log.SetFlags(0)
go func() {
if err := server(addr, handler, timeout); err != nil {
log.Fatal(err)
}
}()
time.Sleep(1 * time.Second) // poor man synchronization with the server
client(addr, delay) // the client will wait forever for the server response
fmt.Println("done")
time.Sleep(1 * time.Second)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment