Skip to content

Instantly share code, notes, and snippets.

@alberts
Created January 26, 2013 07:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alberts/4640746 to your computer and use it in GitHub Desktop.
Save alberts/4640746 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"net"
"net/http"
"sync"
"time"
)
type breaker interface {
done() bool
}
type chanBreaker struct {
c <-chan bool
}
func (cb chanBreaker) done() bool {
select {
case <-cb.c:
return true
default:
}
return false
}
type gg struct {
b breaker
k int
}
func (g *gg) next() ([]byte, error) {
j := 0
for i := 0; i < 1e5; i++ {
if i%10 == 0 && g.b.done() {
fmt.Println("close notification")
return nil, io.EOF
}
j += i
}
s := fmt.Sprintf("hello%d", j)
b := []byte(s + "\n")
g.k += len(b)
fmt.Printf("wrote %d bytes so far\n", g.k)
return b, nil
}
func handleFoo(rw http.ResponseWriter, req *http.Request) {
fmt.Printf("REQUEST: %v\n", req)
cn := rw.(http.CloseNotifier)
cb := chanBreaker{cn.CloseNotify()}
rw.WriteHeader(http.StatusOK)
g := &gg{cb, 0}
for {
b, err := g.next()
if err != nil {
fmt.Println("bombing out here")
break
}
if _, err = rw.Write(b); err != nil {
fmt.Printf("Write: %v\n", err)
break
}
}
fmt.Printf("done writing everything\n")
}
func main() {
l, err := net.Listen("tcp", "127.0.0.1:12034")
if err != nil {
panic(err)
}
mux := http.NewServeMux()
mux.HandleFunc("/foo", handleFoo)
srv := &http.Server{
Handler: mux,
WriteTimeout: 10 * time.Second,
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
err := srv.Serve(l)
fmt.Printf("Serve failed: %v", err)
wg.Done()
}()
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment