Merge pull request #8347 from heyitsanthony/use-from-grpc-md

clientv3: use FromOutgoingContext to bucket watches
This commit is contained in:
Anthony Romano 2017-08-01 17:05:56 -07:00 committed by GitHub
commit d543870966
2 changed files with 24 additions and 14 deletions

View File

@ -30,6 +30,7 @@ import (
"github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/pkg/testutil"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/metadata"
) )
type watcherTest func(*testing.T, *watchctx) type watcherTest func(*testing.T, *watchctx)
@ -875,8 +876,10 @@ func TestWatchCancelOnServer(t *testing.T) {
cancels := make([]context.CancelFunc, numWatches) cancels := make([]context.CancelFunc, numWatches)
for i := 0; i < numWatches; i++ { for i := 0; i < numWatches; i++ {
// use WithTimeout to force separate streams in client // force separate streams in client
ctx, cancel := context.WithTimeout(context.Background(), time.Second) md := metadata.Pairs("some-key", fmt.Sprintf("%d", i))
mctx := metadata.NewOutgoingContext(context.Background(), md)
ctx, cancel := context.WithCancel(mctx)
cancels[i] = cancel cancels[i] = cancel
w := client.Watch(ctx, fmt.Sprintf("%d", i), clientv3.WithCreatedNotify()) w := client.Watch(ctx, fmt.Sprintf("%d", i), clientv3.WithCreatedNotify())
<-w <-w
@ -933,12 +936,12 @@ func testWatchOverlapContextCancel(t *testing.T, f func(*integration.ClusterV3))
clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
defer clus.Terminate(t) defer clus.Terminate(t)
// each unique context "%v" has a unique grpc stream
n := 100 n := 100
ctxs, ctxc := make([]context.Context, 5), make([]chan struct{}, 5) ctxs, ctxc := make([]context.Context, 5), make([]chan struct{}, 5)
for i := range ctxs { for i := range ctxs {
// make "%v" unique // make unique stream
ctxs[i] = context.WithValue(context.TODO(), "key", i) md := metadata.Pairs("some-key", fmt.Sprintf("%d", i))
ctxs[i] = metadata.NewOutgoingContext(context.Background(), md)
// limits the maximum number of outstanding watchers per stream // limits the maximum number of outstanding watchers per stream
ctxc[i] = make(chan struct{}, 2) ctxc[i] = make(chan struct{}, 2)
} }

View File

@ -25,6 +25,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
) )
const ( const (
@ -213,16 +214,15 @@ func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream {
owner: w, owner: w,
remote: w.remote, remote: w.remote,
ctx: ctx, ctx: ctx,
ctxKey: fmt.Sprintf("%v", inctx), ctxKey: streamKeyFromCtx(inctx),
cancel: cancel, cancel: cancel,
substreams: make(map[int64]*watcherStream), substreams: make(map[int64]*watcherStream),
respc: make(chan *pb.WatchResponse),
respc: make(chan *pb.WatchResponse), reqc: make(chan *watchRequest),
reqc: make(chan *watchRequest), donec: make(chan struct{}),
donec: make(chan struct{}), errc: make(chan error, 1),
errc: make(chan error, 1), closingc: make(chan *watcherStream),
closingc: make(chan *watcherStream), resumec: make(chan struct{}),
resumec: make(chan struct{}),
} }
go wgs.run() go wgs.run()
return wgs return wgs
@ -253,7 +253,7 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch
} }
ok := false ok := false
ctxKey := fmt.Sprintf("%v", ctx) ctxKey := streamKeyFromCtx(ctx)
// find or allocate appropriate grpc watch stream // find or allocate appropriate grpc watch stream
w.mu.Lock() w.mu.Lock()
@ -794,3 +794,10 @@ func (wr *watchRequest) toPB() *pb.WatchRequest {
cr := &pb.WatchRequest_CreateRequest{CreateRequest: req} cr := &pb.WatchRequest_CreateRequest{CreateRequest: req}
return &pb.WatchRequest{RequestUnion: cr} return &pb.WatchRequest{RequestUnion: cr}
} }
func streamKeyFromCtx(ctx context.Context) string {
if md, ok := metadata.FromOutgoingContext(ctx); ok {
return fmt.Sprintf("%+v", md)
}
return ""
}