Skip to content

Instantly share code, notes, and snippets.

@mmirolim
Created November 5, 2015 22:00
Show Gist options
  • Select an option

  • Save mmirolim/4088d018c78140838e06 to your computer and use it in GitHub Desktop.

Select an option

Save mmirolim/4088d018c78140838e06 to your computer and use it in GitHub Desktop.
use context with http handlers
package main
import (
"io"
"log"
. "net/http"
"time"
"code.google.com/p/go-uuid/uuid"
"golang.org/x/net/context"
)
type CtxHandlerFunc func(context.Context, ResponseWriter, *Request)
func duration(h CtxHandlerFunc) HandlerFunc {
return func(w ResponseWriter, r *Request) {
s := time.Now()
var (
ctx context.Context
cancel context.CancelFunc
)
ctx, cancel = context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
h(ctx, w, r)
log.Println("req server in ", time.Since(s))
}
}
// middleware to mark request
func identify(h CtxHandlerFunc) CtxHandlerFunc {
return func(ctx context.Context, w ResponseWriter, r *Request) {
h(context.WithValue(ctx, "req_uuid", uuid.New()), w, r)
}
}
func hello(ctx context.Context, w ResponseWriter, r *Request) {
reqID := ctx.Value("req_uuid").(string)
io.WriteString(w, "this is response to request id "+reqID+"\n")
}
func slow(ctx context.Context, w ResponseWriter, r *Request) {
c := make(chan string, 1)
// do it async
go func() {
time.Sleep(90 * time.Millisecond)
reqID := ctx.Value("req_uuid").(string)
c <- "this is response to request id " + reqID + "\n"
}()
// wait to finish or stop by timeout
select {
case res := <-c:
io.WriteString(w, res)
case <-ctx.Done():
io.WriteString(w, "this response canceled by timeout")
}
}
func main() {
HandleFunc("/", duration(identify(hello)))
HandleFunc("/slow", duration(identify(slow)))
log.Fatalln(ListenAndServe(":8080", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment