etcdserver/etcdhttp: break out wait

The assignment of ev was getting burried in the select. This makes it
easier to grok encodeResponse.
release-2.0
Blake Mizerany 2014-08-27 16:34:43 -07:00 committed by Yicheng Qin
parent 8c3450e200
commit c4defbc45c
1 changed files with 26 additions and 14 deletions

View File

@ -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()
}
}