Created
January 7, 2020 14:40
-
-
Save perillo/d111f6400d5b25eef45214c4b0c6d381 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"log" | |
"net/http" | |
"time" | |
) | |
type handler func(http.ResponseWriter, *http.Request) | |
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") | |
_, err := http.Post(addr, "text/plain", body) | |
if err != nil { | |
log.Fatal(err) | |
} | |
return err | |
} | |
func server(addr string, handler handler, timeout time.Duration) error { | |
srv := http.Server{ | |
Addr: addr, | |
Handler: http.HandlerFunc(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() | |
go func() { | |
// 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) | |
} | |
} | |
}() | |
// The handler will never send a response to the poor client. | |
select {} | |
} | |
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); err != nil { | |
log.Fatal(err) | |
} | |
}() | |
time.Sleep(1 * time.Second) // poor man synchronization with the server | |
client(addr) // the client will wait forever for the server response | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment