internal/grpcsync: move CallbackSerializer from xdsclient/internal to here (#6153)

This commit is contained in:
my4 2023-04-01 02:13:33 +09:00 committed by GitHub
parent c2899dddf5
commit e97991991c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 18 deletions

View File

@ -16,7 +16,7 @@
* *
*/ */
package xdsclient package grpcsync
import ( import (
"context" "context"
@ -24,22 +24,22 @@ import (
"google.golang.org/grpc/internal/buffer" "google.golang.org/grpc/internal/buffer"
) )
// callbackSerializer provides a mechanism to schedule callbacks in a // CallbackSerializer provides a mechanism to schedule callbacks in a
// synchronized manner. It provides a FIFO guarantee on the order of execution // synchronized manner. It provides a FIFO guarantee on the order of execution
// of scheduled callbacks. New callbacks can be scheduled by invoking the // of scheduled callbacks. New callbacks can be scheduled by invoking the
// Schedule() method. // Schedule() method.
// //
// This type is safe for concurrent access. // This type is safe for concurrent access.
type callbackSerializer struct { type CallbackSerializer struct {
callbacks *buffer.Unbounded callbacks *buffer.Unbounded
} }
// newCallbackSerializer returns a new callbackSerializer instance. The provided // NewCallbackSerializer returns a new CallbackSerializer instance. The provided
// context will be passed to the scheduled callbacks. Users should cancel the // context will be passed to the scheduled callbacks. Users should cancel the
// provided context to shutdown the callbackSerializer. It is guaranteed that no // provided context to shutdown the CallbackSerializer. It is guaranteed that no
// callbacks will be executed once this context is canceled. // callbacks will be executed once this context is canceled.
func newCallbackSerializer(ctx context.Context) *callbackSerializer { func NewCallbackSerializer(ctx context.Context) *CallbackSerializer {
t := &callbackSerializer{callbacks: buffer.NewUnbounded()} t := &CallbackSerializer{callbacks: buffer.NewUnbounded()}
go t.run(ctx) go t.run(ctx)
return t return t
} }
@ -48,11 +48,11 @@ func newCallbackSerializer(ctx context.Context) *callbackSerializer {
// //
// Callbacks are expected to honor the context when performing any blocking // Callbacks are expected to honor the context when performing any blocking
// operations, and should return early when the context is canceled. // operations, and should return early when the context is canceled.
func (t *callbackSerializer) Schedule(f func(ctx context.Context)) { func (t *CallbackSerializer) Schedule(f func(ctx context.Context)) {
t.callbacks.Put(f) t.callbacks.Put(f)
} }
func (t *callbackSerializer) run(ctx context.Context) { func (t *CallbackSerializer) run(ctx context.Context) {
for ctx.Err() == nil { for ctx.Err() == nil {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -16,7 +16,7 @@
* *
*/ */
package xdsclient package grpcsync
import ( import (
"context" "context"
@ -28,11 +28,16 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
const (
defaultTestTimeout = 5 * time.Second
defaultTestShortTimeout = 10 * time.Millisecond // For events expected to *not* happen.
)
// TestCallbackSerializer_Schedule_FIFO verifies that callbacks are executed in // TestCallbackSerializer_Schedule_FIFO verifies that callbacks are executed in
// the same order in which they were scheduled. // the same order in which they were scheduled.
func (s) TestCallbackSerializer_Schedule_FIFO(t *testing.T) { func (s) TestCallbackSerializer_Schedule_FIFO(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
cs := newCallbackSerializer(ctx) cs := NewCallbackSerializer(ctx)
defer cancel() defer cancel()
// We have two channels, one to record the order of scheduling, and the // We have two channels, one to record the order of scheduling, and the
@ -100,7 +105,7 @@ func (s) TestCallbackSerializer_Schedule_FIFO(t *testing.T) {
// scheduled callbacks get executed. // scheduled callbacks get executed.
func (s) TestCallbackSerializer_Schedule_Concurrent(t *testing.T) { func (s) TestCallbackSerializer_Schedule_Concurrent(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
cs := newCallbackSerializer(ctx) cs := NewCallbackSerializer(ctx)
defer cancel() defer cancel()
// Schedule callbacks concurrently by calling Schedule() from goroutines. // Schedule callbacks concurrently by calling Schedule() from goroutines.
@ -136,7 +141,7 @@ func (s) TestCallbackSerializer_Schedule_Concurrent(t *testing.T) {
// are not executed once Close() returns. // are not executed once Close() returns.
func (s) TestCallbackSerializer_Schedule_Close(t *testing.T) { func (s) TestCallbackSerializer_Schedule_Close(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
cs := newCallbackSerializer(ctx) cs := NewCallbackSerializer(ctx)
// Schedule a callback which blocks until the context passed to it is // Schedule a callback which blocks until the context passed to it is
// canceled. It also closes a couple of channels to signal that it started // canceled. It also closes a couple of channels to signal that it started

View File

@ -26,6 +26,7 @@ import (
"time" "time"
"google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/xds/internal/xdsclient/bootstrap" "google.golang.org/grpc/xds/internal/xdsclient/bootstrap"
"google.golang.org/grpc/xds/internal/xdsclient/load" "google.golang.org/grpc/xds/internal/xdsclient/load"
"google.golang.org/grpc/xds/internal/xdsclient/transport" "google.golang.org/grpc/xds/internal/xdsclient/transport"
@ -65,7 +66,7 @@ type authority struct {
serverCfg *bootstrap.ServerConfig // Server config for this authority serverCfg *bootstrap.ServerConfig // Server config for this authority
bootstrapCfg *bootstrap.Config // Full bootstrap configuration bootstrapCfg *bootstrap.Config // Full bootstrap configuration
refCount int // Reference count of watches referring to this authority refCount int // Reference count of watches referring to this authority
serializer *callbackSerializer // Callback serializer for invoking watch callbacks serializer *grpcsync.CallbackSerializer // Callback serializer for invoking watch callbacks
resourceTypeGetter func(string) xdsresource.Type // ResourceType registry lookup resourceTypeGetter func(string) xdsresource.Type // ResourceType registry lookup
transport *transport.Transport // Underlying xDS transport to the management server transport *transport.Transport // Underlying xDS transport to the management server
watchExpiryTimeout time.Duration // Resource watch expiry timeout watchExpiryTimeout time.Duration // Resource watch expiry timeout
@ -99,7 +100,7 @@ type authorityArgs struct {
// the second case. // the second case.
serverCfg *bootstrap.ServerConfig serverCfg *bootstrap.ServerConfig
bootstrapCfg *bootstrap.Config bootstrapCfg *bootstrap.Config
serializer *callbackSerializer serializer *grpcsync.CallbackSerializer
resourceTypeGetter func(string) xdsresource.Type resourceTypeGetter func(string) xdsresource.Type
watchExpiryTimeout time.Duration watchExpiryTimeout time.Duration
logger *grpclog.PrefixLogger logger *grpclog.PrefixLogger

View File

@ -25,6 +25,7 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/testutils/xds/e2e" "google.golang.org/grpc/internal/testutils/xds/e2e"
"google.golang.org/grpc/xds/internal" "google.golang.org/grpc/xds/internal"
"google.golang.org/grpc/xds/internal/testutils" "google.golang.org/grpc/xds/internal/testutils"
@ -69,7 +70,7 @@ func setupTest(ctx context.Context, t *testing.T, opts e2e.ManagementServerOptio
bootstrapCfg: &bootstrap.Config{ bootstrapCfg: &bootstrap.Config{
NodeProto: &v3corepb.Node{Id: nodeID}, NodeProto: &v3corepb.Node{Id: nodeID},
}, },
serializer: newCallbackSerializer(ctx), serializer: grpcsync.NewCallbackSerializer(ctx),
resourceTypeGetter: rtRegistry.get, resourceTypeGetter: rtRegistry.get,
watchExpiryTimeout: watchExpiryTimeout, watchExpiryTimeout: watchExpiryTimeout,
logger: nil, logger: nil,

View File

@ -69,7 +69,7 @@ func newWithConfig(config *bootstrap.Config, watchExpiryTimeout time.Duration, i
done: grpcsync.NewEvent(), done: grpcsync.NewEvent(),
config: config, config: config,
watchExpiryTimeout: watchExpiryTimeout, watchExpiryTimeout: watchExpiryTimeout,
serializer: newCallbackSerializer(ctx), serializer: grpcsync.NewCallbackSerializer(ctx),
serializerClose: cancel, serializerClose: cancel,
resourceTypes: newResourceTypeRegistry(), resourceTypes: newResourceTypeRegistry(),
authorities: make(map[string]*authority), authorities: make(map[string]*authority),

View File

@ -37,7 +37,7 @@ type clientImpl struct {
config *bootstrap.Config config *bootstrap.Config
logger *grpclog.PrefixLogger logger *grpclog.PrefixLogger
watchExpiryTimeout time.Duration watchExpiryTimeout time.Duration
serializer *callbackSerializer serializer *grpcsync.CallbackSerializer
serializerClose func() serializerClose func()
resourceTypes *resourceTypeRegistry resourceTypes *resourceTypeRegistry