balancer.go raw

   1  /*
   2   *
   3   * Copyright 2017 gRPC authors.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   *
  17   */
  18  
  19  // Package balancer defines APIs for load balancing in gRPC.
  20  // All APIs in this package are experimental.
  21  package balancer
  22  
  23  import (
  24  	"context"
  25  	"encoding/json"
  26  	"errors"
  27  	"net"
  28  	"strings"
  29  
  30  	"google.golang.org/grpc/channelz"
  31  	"google.golang.org/grpc/connectivity"
  32  	"google.golang.org/grpc/credentials"
  33  	estats "google.golang.org/grpc/experimental/stats"
  34  	"google.golang.org/grpc/grpclog"
  35  	"google.golang.org/grpc/internal"
  36  	"google.golang.org/grpc/metadata"
  37  	"google.golang.org/grpc/resolver"
  38  	"google.golang.org/grpc/serviceconfig"
  39  )
  40  
  41  var (
  42  	// m is a map from name to balancer builder.
  43  	m = make(map[string]Builder)
  44  
  45  	logger = grpclog.Component("balancer")
  46  )
  47  
  48  // Register registers the balancer builder to the balancer map. b.Name
  49  // (lowercased) will be used as the name registered with this builder.  If the
  50  // Builder implements ConfigParser, ParseConfig will be called when new service
  51  // configs are received by the resolver, and the result will be provided to the
  52  // Balancer in UpdateClientConnState.
  53  //
  54  // NOTE: this function must only be called during initialization time (i.e. in
  55  // an init() function), and is not thread-safe. If multiple Balancers are
  56  // registered with the same name, the one registered last will take effect.
  57  func Register(b Builder) {
  58  	name := strings.ToLower(b.Name())
  59  	if name != b.Name() {
  60  		// TODO: Skip the use of strings.ToLower() to index the map after v1.59
  61  		// is released to switch to case sensitive balancer registry. Also,
  62  		// remove this warning and update the docstrings for Register and Get.
  63  		logger.Warningf("Balancer registered with name %q. grpc-go will be switching to case sensitive balancer registries soon", b.Name())
  64  	}
  65  	m[name] = b
  66  }
  67  
  68  // unregisterForTesting deletes the balancer with the given name from the
  69  // balancer map.
  70  //
  71  // This function is not thread-safe.
  72  func unregisterForTesting(name string) {
  73  	delete(m, name)
  74  }
  75  
  76  func init() {
  77  	internal.BalancerUnregister = unregisterForTesting
  78  	internal.ConnectedAddress = connectedAddress
  79  	internal.SetConnectedAddress = setConnectedAddress
  80  }
  81  
  82  // Get returns the resolver builder registered with the given name.
  83  // Note that the compare is done in a case-insensitive fashion.
  84  // If no builder is register with the name, nil will be returned.
  85  func Get(name string) Builder {
  86  	if strings.ToLower(name) != name {
  87  		// TODO: Skip the use of strings.ToLower() to index the map after v1.59
  88  		// is released to switch to case sensitive balancer registry. Also,
  89  		// remove this warning and update the docstrings for Register and Get.
  90  		logger.Warningf("Balancer retrieved for name %q. grpc-go will be switching to case sensitive balancer registries soon", name)
  91  	}
  92  	if b, ok := m[strings.ToLower(name)]; ok {
  93  		return b
  94  	}
  95  	return nil
  96  }
  97  
  98  // NewSubConnOptions contains options to create new SubConn.
  99  type NewSubConnOptions struct {
 100  	// CredsBundle is the credentials bundle that will be used in the created
 101  	// SubConn. If it's nil, the original creds from grpc DialOptions will be
 102  	// used.
 103  	//
 104  	// Deprecated: Use the Attributes field in resolver.Address to pass
 105  	// arbitrary data to the credential handshaker.
 106  	CredsBundle credentials.Bundle
 107  	// HealthCheckEnabled indicates whether health check service should be
 108  	// enabled on this SubConn
 109  	HealthCheckEnabled bool
 110  	// StateListener is called when the state of the subconn changes.  If nil,
 111  	// Balancer.UpdateSubConnState will be called instead.  Will never be
 112  	// invoked until after Connect() is called on the SubConn created with
 113  	// these options.
 114  	StateListener func(SubConnState)
 115  }
 116  
 117  // State contains the balancer's state relevant to the gRPC ClientConn.
 118  type State struct {
 119  	// State contains the connectivity state of the balancer, which is used to
 120  	// determine the state of the ClientConn.
 121  	ConnectivityState connectivity.State
 122  	// Picker is used to choose connections (SubConns) for RPCs.
 123  	Picker Picker
 124  }
 125  
 126  // ClientConn represents a gRPC ClientConn.
 127  //
 128  // This interface is to be implemented by gRPC. Users should not need a
 129  // brand new implementation of this interface. For the situations like
 130  // testing, the new implementation should embed this interface. This allows
 131  // gRPC to add new methods to this interface.
 132  //
 133  // NOTICE: This interface is intended to be implemented by gRPC, or intercepted
 134  // by custom load balancing polices.  Users should not need their own complete
 135  // implementation of this interface -- they should always delegate to a
 136  // ClientConn passed to Builder.Build() by embedding it in their
 137  // implementations. An embedded ClientConn must never be nil, or runtime panics
 138  // will occur.
 139  type ClientConn interface {
 140  	// NewSubConn is called by balancer to create a new SubConn.
 141  	// It doesn't block and wait for the connections to be established.
 142  	// Behaviors of the SubConn can be controlled by options.
 143  	//
 144  	// Deprecated: please be aware that in a future version, SubConns will only
 145  	// support one address per SubConn.
 146  	NewSubConn([]resolver.Address, NewSubConnOptions) (SubConn, error)
 147  	// RemoveSubConn removes the SubConn from ClientConn.
 148  	// The SubConn will be shutdown.
 149  	//
 150  	// Deprecated: use SubConn.Shutdown instead.
 151  	RemoveSubConn(SubConn)
 152  	// UpdateAddresses updates the addresses used in the passed in SubConn.
 153  	// gRPC checks if the currently connected address is still in the new list.
 154  	// If so, the connection will be kept. Else, the connection will be
 155  	// gracefully closed, and a new connection will be created.
 156  	//
 157  	// This may trigger a state transition for the SubConn.
 158  	//
 159  	// Deprecated: this method will be removed.  Create new SubConns for new
 160  	// addresses instead.
 161  	UpdateAddresses(SubConn, []resolver.Address)
 162  
 163  	// UpdateState notifies gRPC that the balancer's internal state has
 164  	// changed.
 165  	//
 166  	// gRPC will update the connectivity state of the ClientConn, and will call
 167  	// Pick on the new Picker to pick new SubConns.
 168  	UpdateState(State)
 169  
 170  	// ResolveNow is called by balancer to notify gRPC to do a name resolving.
 171  	ResolveNow(resolver.ResolveNowOptions)
 172  
 173  	// Target returns the dial target for this ClientConn.
 174  	//
 175  	// Deprecated: Use the Target field in the BuildOptions instead.
 176  	Target() string
 177  
 178  	// MetricsRecorder provides the metrics recorder that balancers can use to
 179  	// record metrics. Balancer implementations which do not register metrics on
 180  	// metrics registry and record on them can ignore this method. The returned
 181  	// MetricsRecorder is guaranteed to never be nil.
 182  	MetricsRecorder() estats.MetricsRecorder
 183  
 184  	// EnforceClientConnEmbedding is included to force implementers to embed
 185  	// another implementation of this interface, allowing gRPC to add methods
 186  	// without breaking users.
 187  	internal.EnforceClientConnEmbedding
 188  }
 189  
 190  // BuildOptions contains additional information for Build.
 191  type BuildOptions struct {
 192  	// DialCreds is the transport credentials to use when communicating with a
 193  	// remote load balancer server. Balancer implementations which do not
 194  	// communicate with a remote load balancer server can ignore this field.
 195  	DialCreds credentials.TransportCredentials
 196  	// CredsBundle is the credentials bundle to use when communicating with a
 197  	// remote load balancer server. Balancer implementations which do not
 198  	// communicate with a remote load balancer server can ignore this field.
 199  	CredsBundle credentials.Bundle
 200  	// Dialer is the custom dialer to use when communicating with a remote load
 201  	// balancer server. Balancer implementations which do not communicate with a
 202  	// remote load balancer server can ignore this field.
 203  	Dialer func(context.Context, string) (net.Conn, error)
 204  	// Authority is the server name to use as part of the authentication
 205  	// handshake when communicating with a remote load balancer server. Balancer
 206  	// implementations which do not communicate with a remote load balancer
 207  	// server can ignore this field.
 208  	Authority string
 209  	// ChannelzParent is the parent ClientConn's channelz channel.
 210  	ChannelzParent channelz.Identifier
 211  	// CustomUserAgent is the custom user agent set on the parent ClientConn.
 212  	// The balancer should set the same custom user agent if it creates a
 213  	// ClientConn.
 214  	CustomUserAgent string
 215  	// Target contains the parsed address info of the dial target. It is the
 216  	// same resolver.Target as passed to the resolver. See the documentation for
 217  	// the resolver.Target type for details about what it contains.
 218  	Target resolver.Target
 219  }
 220  
 221  // Builder creates a balancer.
 222  type Builder interface {
 223  	// Build creates a new balancer with the ClientConn.
 224  	Build(cc ClientConn, opts BuildOptions) Balancer
 225  	// Name returns the name of balancers built by this builder.
 226  	// It will be used to pick balancers (for example in service config).
 227  	Name() string
 228  }
 229  
 230  // ConfigParser parses load balancer configs.
 231  type ConfigParser interface {
 232  	// ParseConfig parses the JSON load balancer config provided into an
 233  	// internal form or returns an error if the config is invalid.  For future
 234  	// compatibility reasons, unknown fields in the config should be ignored.
 235  	ParseConfig(LoadBalancingConfigJSON json.RawMessage) (serviceconfig.LoadBalancingConfig, error)
 236  }
 237  
 238  // PickInfo contains additional information for the Pick operation.
 239  type PickInfo struct {
 240  	// FullMethodName is the method name that NewClientStream() is called
 241  	// with. The canonical format is /service/Method.
 242  	FullMethodName string
 243  	// Ctx is the RPC's context, and may contain relevant RPC-level information
 244  	// like the outgoing header metadata.
 245  	Ctx context.Context
 246  }
 247  
 248  // DoneInfo contains additional information for done.
 249  type DoneInfo struct {
 250  	// Err is the rpc error the RPC finished with. It could be nil.
 251  	Err error
 252  	// Trailer contains the metadata from the RPC's trailer, if present.
 253  	Trailer metadata.MD
 254  	// BytesSent indicates if any bytes have been sent to the server.
 255  	BytesSent bool
 256  	// BytesReceived indicates if any byte has been received from the server.
 257  	BytesReceived bool
 258  	// ServerLoad is the load received from server. It's usually sent as part of
 259  	// trailing metadata.
 260  	//
 261  	// The only supported type now is *orca_v3.LoadReport.
 262  	ServerLoad any
 263  }
 264  
 265  var (
 266  	// ErrNoSubConnAvailable indicates no SubConn is available for pick().
 267  	// gRPC will block the RPC until a new picker is available via UpdateState().
 268  	ErrNoSubConnAvailable = errors.New("no SubConn is available")
 269  	// ErrTransientFailure indicates all SubConns are in TransientFailure.
 270  	// WaitForReady RPCs will block, non-WaitForReady RPCs will fail.
 271  	//
 272  	// Deprecated: return an appropriate error based on the last resolution or
 273  	// connection attempt instead.  The behavior is the same for any non-gRPC
 274  	// status error.
 275  	ErrTransientFailure = errors.New("all SubConns are in TransientFailure")
 276  )
 277  
 278  // PickResult contains information related to a connection chosen for an RPC.
 279  type PickResult struct {
 280  	// SubConn is the connection to use for this pick, if its state is Ready.
 281  	// If the state is not Ready, gRPC will block the RPC until a new Picker is
 282  	// provided by the balancer (using ClientConn.UpdateState).  The SubConn
 283  	// must be one returned by ClientConn.NewSubConn.
 284  	SubConn SubConn
 285  
 286  	// Done is called when the RPC is completed.  If the SubConn is not ready,
 287  	// this will be called with a nil parameter.  If the SubConn is not a valid
 288  	// type, Done may not be called.  May be nil if the balancer does not wish
 289  	// to be notified when the RPC completes.
 290  	Done func(DoneInfo)
 291  
 292  	// Metadata provides a way for LB policies to inject arbitrary per-call
 293  	// metadata. Any metadata returned here will be merged with existing
 294  	// metadata added by the client application.
 295  	//
 296  	// LB policies with child policies are responsible for propagating metadata
 297  	// injected by their children to the ClientConn, as part of Pick().
 298  	Metadata metadata.MD
 299  }
 300  
 301  // TransientFailureError returns e.  It exists for backward compatibility and
 302  // will be deleted soon.
 303  //
 304  // Deprecated: no longer necessary, picker errors are treated this way by
 305  // default.
 306  func TransientFailureError(e error) error { return e }
 307  
 308  // Picker is used by gRPC to pick a SubConn to send an RPC.
 309  // Balancer is expected to generate a new picker from its snapshot every time its
 310  // internal state has changed.
 311  //
 312  // The pickers used by gRPC can be updated by ClientConn.UpdateState().
 313  type Picker interface {
 314  	// Pick returns the connection to use for this RPC and related information.
 315  	//
 316  	// Pick should not block.  If the balancer needs to do I/O or any blocking
 317  	// or time-consuming work to service this call, it should return
 318  	// ErrNoSubConnAvailable, and the Pick call will be repeated by gRPC when
 319  	// the Picker is updated (using ClientConn.UpdateState).
 320  	//
 321  	// If an error is returned:
 322  	//
 323  	// - If the error is ErrNoSubConnAvailable, gRPC will block until a new
 324  	//   Picker is provided by the balancer (using ClientConn.UpdateState).
 325  	//
 326  	// - If the error is a status error (implemented by the grpc/status
 327  	//   package), gRPC will terminate the RPC with the code and message
 328  	//   provided.
 329  	//
 330  	// - For all other errors, wait for ready RPCs will wait, but non-wait for
 331  	//   ready RPCs will be terminated with this error's Error() string and
 332  	//   status code Unavailable.
 333  	Pick(info PickInfo) (PickResult, error)
 334  }
 335  
 336  // Balancer takes input from gRPC, manages SubConns, and collects and aggregates
 337  // the connectivity states.
 338  //
 339  // It also generates and updates the Picker used by gRPC to pick SubConns for RPCs.
 340  //
 341  // UpdateClientConnState, ResolverError, UpdateSubConnState, and Close are
 342  // guaranteed to be called synchronously from the same goroutine.  There's no
 343  // guarantee on picker.Pick, it may be called anytime.
 344  type Balancer interface {
 345  	// UpdateClientConnState is called by gRPC when the state of the ClientConn
 346  	// changes.  If the error returned is ErrBadResolverState, the ClientConn
 347  	// will begin calling ResolveNow on the active name resolver with
 348  	// exponential backoff until a subsequent call to UpdateClientConnState
 349  	// returns a nil error.  Any other errors are currently ignored.
 350  	UpdateClientConnState(ClientConnState) error
 351  	// ResolverError is called by gRPC when the name resolver reports an error.
 352  	ResolverError(error)
 353  	// UpdateSubConnState is called by gRPC when the state of a SubConn
 354  	// changes.
 355  	//
 356  	// Deprecated: Use NewSubConnOptions.StateListener when creating the
 357  	// SubConn instead.
 358  	UpdateSubConnState(SubConn, SubConnState)
 359  	// Close closes the balancer. The balancer is not currently required to
 360  	// call SubConn.Shutdown for its existing SubConns; however, this will be
 361  	// required in a future release, so it is recommended.
 362  	Close()
 363  	// ExitIdle instructs the LB policy to reconnect to backends / exit the
 364  	// IDLE state, if appropriate and possible.  Note that SubConns that enter
 365  	// the IDLE state will not reconnect until SubConn.Connect is called.
 366  	ExitIdle()
 367  }
 368  
 369  // ExitIdler is an optional interface for balancers to implement.  If
 370  // implemented, ExitIdle will be called when ClientConn.Connect is called, if
 371  // the ClientConn is idle.  If unimplemented, ClientConn.Connect will cause
 372  // all SubConns to connect.
 373  //
 374  // Deprecated: All balancers must implement this interface. This interface will
 375  // be removed in a future release.
 376  type ExitIdler interface {
 377  	// ExitIdle instructs the LB policy to reconnect to backends / exit the
 378  	// IDLE state, if appropriate and possible.  Note that SubConns that enter
 379  	// the IDLE state will not reconnect until SubConn.Connect is called.
 380  	ExitIdle()
 381  }
 382  
 383  // ClientConnState describes the state of a ClientConn relevant to the
 384  // balancer.
 385  type ClientConnState struct {
 386  	ResolverState resolver.State
 387  	// The parsed load balancing configuration returned by the builder's
 388  	// ParseConfig method, if implemented.
 389  	BalancerConfig serviceconfig.LoadBalancingConfig
 390  }
 391  
 392  // ErrBadResolverState may be returned by UpdateClientConnState to indicate a
 393  // problem with the provided name resolver data.
 394  var ErrBadResolverState = errors.New("bad resolver state")
 395