client: add SyncableHTTPClient.Endpoints

This commit is contained in:
Brian Waldon 2014-11-06 10:53:20 -08:00
parent 2760739ceb
commit 4b555dba99
2 changed files with 19 additions and 12 deletions

View File

@ -40,6 +40,7 @@ var (
type SyncableHTTPClient interface { type SyncableHTTPClient interface {
HTTPClient HTTPClient
Sync(context.Context) error Sync(context.Context) error
Endpoints() []string
} }
type HTTPClient interface { type HTTPClient interface {
@ -65,7 +66,8 @@ func NewHTTPClient(tr CancelableTransport, eps []string) (SyncableHTTPClient, er
func newHTTPClusterClient(tr CancelableTransport, eps []string) (*httpClusterClient, error) { func newHTTPClusterClient(tr CancelableTransport, eps []string) (*httpClusterClient, error) {
c := httpClusterClient{ c := httpClusterClient{
transport: tr, transport: tr,
endpoints: make([]HTTPClient, len(eps)), endpoints: eps,
clients: make([]HTTPClient, len(eps)),
} }
for i, ep := range eps { for i, ep := range eps {
@ -74,7 +76,7 @@ func newHTTPClusterClient(tr CancelableTransport, eps []string) (*httpClusterCli
return nil, err return nil, err
} }
c.endpoints[i] = &redirectFollowingHTTPClient{ c.clients[i] = &redirectFollowingHTTPClient{
max: DefaultMaxRedirects, max: DefaultMaxRedirects,
client: &httpClient{ client: &httpClient{
transport: tr, transport: tr,
@ -88,14 +90,15 @@ func newHTTPClusterClient(tr CancelableTransport, eps []string) (*httpClusterCli
type httpClusterClient struct { type httpClusterClient struct {
transport CancelableTransport transport CancelableTransport
endpoints []HTTPClient endpoints []string
clients []HTTPClient
} }
func (c *httpClusterClient) Do(ctx context.Context, act HTTPAction) (resp *http.Response, body []byte, err error) { func (c *httpClusterClient) Do(ctx context.Context, act HTTPAction) (resp *http.Response, body []byte, err error) {
if len(c.endpoints) == 0 { if len(c.clients) == 0 {
return nil, nil, ErrNoEndpoints return nil, nil, ErrNoEndpoints
} }
for _, hc := range c.endpoints { for _, hc := range c.clients {
resp, body, err = hc.Do(ctx, act) resp, body, err = hc.Do(ctx, act)
if err != nil { if err != nil {
if err == ErrTimeout || err == ErrCanceled { if err == ErrTimeout || err == ErrCanceled {
@ -111,6 +114,10 @@ func (c *httpClusterClient) Do(ctx context.Context, act HTTPAction) (resp *http.
return return
} }
func (c *httpClusterClient) Endpoints() []string {
return c.endpoints
}
func (c *httpClusterClient) Sync(ctx context.Context) error { func (c *httpClusterClient) Sync(ctx context.Context) error {
mAPI := NewMembersAPI(c) mAPI := NewMembersAPI(c)
ms, err := mAPI.List(ctx) ms, err := mAPI.List(ctx)

View File

@ -193,7 +193,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// first good response short-circuits Do // first good response short-circuits Do
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{ clients: []HTTPClient{
&staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}}, &staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}},
&staticHTTPClient{err: fakeErr}, &staticHTTPClient{err: fakeErr},
}, },
@ -204,7 +204,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// fall through to good endpoint if err is arbitrary // fall through to good endpoint if err is arbitrary
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{ clients: []HTTPClient{
&staticHTTPClient{err: fakeErr}, &staticHTTPClient{err: fakeErr},
&staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}}, &staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}},
}, },
@ -215,7 +215,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// ErrTimeout short-circuits Do // ErrTimeout short-circuits Do
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{ clients: []HTTPClient{
&staticHTTPClient{err: ErrTimeout}, &staticHTTPClient{err: ErrTimeout},
&staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}}, &staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}},
}, },
@ -226,7 +226,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// ErrCanceled short-circuits Do // ErrCanceled short-circuits Do
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{ clients: []HTTPClient{
&staticHTTPClient{err: ErrCanceled}, &staticHTTPClient{err: ErrCanceled},
&staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}}, &staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}},
}, },
@ -237,7 +237,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// return err if there are no endpoints // return err if there are no endpoints
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{}, clients: []HTTPClient{},
}, },
wantErr: ErrNoEndpoints, wantErr: ErrNoEndpoints,
}, },
@ -245,7 +245,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// return err if all endpoints return arbitrary errors // return err if all endpoints return arbitrary errors
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{ clients: []HTTPClient{
&staticHTTPClient{err: fakeErr}, &staticHTTPClient{err: fakeErr},
&staticHTTPClient{err: fakeErr}, &staticHTTPClient{err: fakeErr},
}, },
@ -256,7 +256,7 @@ func TestHTTPClusterClientDo(t *testing.T) {
// 500-level errors cause Do to fallthrough to next endpoint // 500-level errors cause Do to fallthrough to next endpoint
{ {
client: &httpClusterClient{ client: &httpClusterClient{
endpoints: []HTTPClient{ clients: []HTTPClient{
&staticHTTPClient{resp: http.Response{StatusCode: http.StatusBadGateway}}, &staticHTTPClient{resp: http.Response{StatusCode: http.StatusBadGateway}},
&staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}}, &staticHTTPClient{resp: http.Response{StatusCode: http.StatusTeapot}},
}, },