From c4defbc45cfeeda49bea3c72750c65a6bb857057 Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Wed, 27 Aug 2014 16:34:43 -0700 Subject: [PATCH] etcdserver/etcdhttp: break out wait The assignment of ev was getting burried in the select. This makes it easier to grok encodeResponse. --- etcdserver2/etcdhttp/http.go | 40 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/etcdserver2/etcdhttp/http.go b/etcdserver2/etcdhttp/http.go index bf4b56580..4cd8492ad 100644 --- a/etcdserver2/etcdhttp/http.go +++ b/etcdserver2/etcdhttp/http.go @@ -2,6 +2,7 @@ package etcdhttp import ( "encoding/json" + "errors" "fmt" "net/http" "time" @@ -11,6 +12,8 @@ import ( "github.com/coreos/etcd/store" ) +var errClosed = errors.New("etcdhttp: client closed connection") + const DefaultTimeout = 500 * time.Millisecond type Handler struct { @@ -50,25 +53,15 @@ func parseRequest(r *http.Request) (etcdserver.Request, error) { return etcdserver.Request{}, nil } -func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response) error { +func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response) (err error) { var ev *store.Event switch { case resp.Event != nil: ev = resp.Event case resp.Watcher != nil: - // TODO(bmizerany): support streaming? - defer resp.Watcher.Remove() - var nch <-chan bool - if x, ok := w.(http.CloseNotifier); ok { - nch = x.CloseNotify() - } - select { - case ev = <-resp.Watcher.EventChan: - case <-nch: - // TODO: log something? - return nil - case <-ctx.Done(): - return ctx.Err() + ev, err = waitForEvent(ctx, w, resp.Watcher) + if err != nil { + return err } default: panic("should not be rechable") @@ -88,3 +81,22 @@ func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver. } return nil } + +func waitForEvent(ctx context.Context, w http.ResponseWriter, wa *store.Watcher) (*store.Event, error) { + // TODO(bmizerany): support streaming? + defer wa.Remove() + var nch <-chan bool + if x, ok := w.(http.CloseNotifier); ok { + nch = x.CloseNotify() + } + + select { + case ev := <-wa.EventChan: + return ev, nil + case <-nch: + // TODO: log something? + return nil, errClosed + case <-ctx.Done(): + return nil, ctx.Err() + } +}