chore(server): handle HEAD for key space efficiently

Implement HEAD in server/v1 and server/v2 functions to avoid
time wasting on JSON marhsal.
release-0.4
Yicheng Qin 2014-04-07 18:55:07 -07:00
parent 28f19dec60
commit 89d3df242c
3 changed files with 28 additions and 21 deletions

View File

@ -142,20 +142,9 @@ func (s *Server) installDebug(r *mux.Router) {
r.HandleFunc("/debug/pprof/{name}", pprof.Index)
}
type HEADResponseWriter struct {
http.ResponseWriter
}
func (w *HEADResponseWriter) Write([]byte) (int, error) {
return 0, nil
}
// Adds a v1 server handler to the router.
func (s *Server) handleFuncV1(r *mux.Router, path string, f func(http.ResponseWriter, *http.Request, v1.Server) error) *mux.Route {
return s.handleFunc(r, path, func(w http.ResponseWriter, req *http.Request) error {
if req.Method == "HEAD" {
w = &HEADResponseWriter{w}
}
return f(w, req, s)
})
}
@ -163,13 +152,18 @@ func (s *Server) handleFuncV1(r *mux.Router, path string, f func(http.ResponseWr
// Adds a v2 server handler to the router.
func (s *Server) handleFuncV2(r *mux.Router, path string, f func(http.ResponseWriter, *http.Request, v2.Server) error) *mux.Route {
return s.handleFunc(r, path, func(w http.ResponseWriter, req *http.Request) error {
if req.Method == "HEAD" {
w = &HEADResponseWriter{w}
}
return f(w, req, s)
})
}
type HEADResponseWriter struct {
http.ResponseWriter
}
func (w *HEADResponseWriter) Write([]byte) (int, error) {
return 0, nil
}
// Adds a server handler to the router.
func (s *Server) handleFunc(r *mux.Router, path string, f func(http.ResponseWriter, *http.Request) error) *mux.Route {

View File

@ -18,11 +18,14 @@ func GetKeyHandler(w http.ResponseWriter, req *http.Request, s Server) error {
return err
}
w.WriteHeader(http.StatusOK)
if req.Method == "HEAD" {
return nil
}
// Convert event to a response and write to client.
b, _ := json.Marshal(event.Response(s.Store().Index()))
w.WriteHeader(http.StatusOK)
w.Write(b)
return nil
}

View File

@ -41,13 +41,13 @@ func GetHandler(w http.ResponseWriter, req *http.Request, s Server) error {
stream := (req.FormValue("stream") == "true")
if req.FormValue("wait") == "true" {
return handleWatch(key, recursive, stream, waitIndex, w, s)
return handleWatch(key, recursive, stream, waitIndex, w, req, s)
}
return handleGet(key, recursive, sort, w, s)
return handleGet(key, recursive, sort, w, req, s)
}
func handleWatch(key string, recursive, stream bool, waitIndex string, w http.ResponseWriter, s Server) error {
func handleWatch(key string, recursive, stream bool, waitIndex string, w http.ResponseWriter, req *http.Request, s Server) error {
// Create a command to watch from a given index (default 0).
var sinceIndex uint64 = 0
var err error
@ -84,6 +84,9 @@ func handleWatch(key string, recursive, stream bool, waitIndex string, w http.Re
// send to the client in time. Then we simply end streaming.
return nil
}
if req.Method == "HEAD" {
continue
}
b, _ := json.Marshal(event)
_, err := w.Write(b)
@ -99,18 +102,25 @@ func handleWatch(key string, recursive, stream bool, waitIndex string, w http.Re
case <-closeChan:
watcher.Remove()
case event := <-watcher.EventChan:
if req.Method == "HEAD" {
return nil
}
b, _ := json.Marshal(event)
w.Write(b)
}
return nil
}
func handleGet(key string, recursive, sort bool, w http.ResponseWriter, s Server) error {
func handleGet(key string, recursive, sort bool, w http.ResponseWriter, req *http.Request, s Server) error {
event, err := s.Store().Get(key, recursive, sort)
if err != nil {
return err
}
if req.Method == "HEAD" {
return nil
}
writeHeaders(w, s)
b, _ := json.Marshal(event)
w.Write(b)