github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go (about)

     1  // Copyright (C) MongoDB, Inc. 2022-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package driver // import "go.mongodb.org/mongo-driver/x/mongo/driver"
     8  
     9  import (
    10  	"context"
    11  	"time"
    12  
    13  	"go.mongodb.org/mongo-driver/internal"
    14  	"go.mongodb.org/mongo-driver/mongo/address"
    15  	"go.mongodb.org/mongo-driver/mongo/description"
    16  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
    17  	"go.mongodb.org/mongo-driver/x/mongo/driver/session"
    18  )
    19  
    20  // Deployment is implemented by types that can select a server from a deployment.
    21  type Deployment interface {
    22  	SelectServer(context.Context, description.ServerSelector) (Server, error)
    23  	Kind() description.TopologyKind
    24  }
    25  
    26  // Connector represents a type that can connect to a server.
    27  type Connector interface {
    28  	Connect() error
    29  }
    30  
    31  // Disconnector represents a type that can disconnect from a server.
    32  type Disconnector interface {
    33  	Disconnect(context.Context) error
    34  }
    35  
    36  // Subscription represents a subscription to topology updates. A subscriber can receive updates through the
    37  // Updates field.
    38  type Subscription struct {
    39  	Updates <-chan description.Topology
    40  	ID      uint64
    41  }
    42  
    43  // Subscriber represents a type to which another type can subscribe. A subscription contains a channel that
    44  // is updated with topology descriptions.
    45  type Subscriber interface {
    46  	Subscribe() (*Subscription, error)
    47  	Unsubscribe(*Subscription) error
    48  }
    49  
    50  // Server represents a MongoDB server. Implementations should pool connections and handle the
    51  // retrieving and returning of connections.
    52  type Server interface {
    53  	Connection(context.Context) (Connection, error)
    54  
    55  	// RTTMonitor returns the round-trip time monitor associated with this server.
    56  	RTTMonitor() RTTMonitor
    57  }
    58  
    59  // Connection represents a connection to a MongoDB server.
    60  type Connection interface {
    61  	WriteWireMessage(context.Context, []byte) error
    62  	ReadWireMessage(ctx context.Context) ([]byte, error)
    63  	Description() description.Server
    64  
    65  	// Close closes any underlying connection and returns or frees any resources held by the
    66  	// connection. Close is idempotent and can be called multiple times, although subsequent calls
    67  	// to Close may return an error. A connection cannot be used after it is closed.
    68  	Close() error
    69  
    70  	ID() string
    71  	ServerConnectionID() *int64
    72  	DriverConnectionID() uint64 // TODO(GODRIVER-2824): change type to int64.
    73  	Address() address.Address
    74  	Stale() bool
    75  }
    76  
    77  // RTTMonitor represents a round-trip-time monitor.
    78  type RTTMonitor interface {
    79  	// EWMA returns the exponentially weighted moving average observed round-trip time.
    80  	EWMA() time.Duration
    81  
    82  	// Min returns the minimum observed round-trip time over the window period.
    83  	Min() time.Duration
    84  
    85  	// P90 returns the 90th percentile observed round-trip time over the window period.
    86  	P90() time.Duration
    87  
    88  	// Stats returns stringified stats of the current state of the monitor.
    89  	Stats() string
    90  }
    91  
    92  var _ RTTMonitor = &internal.ZeroRTTMonitor{}
    93  
    94  // PinnedConnection represents a Connection that can be pinned by one or more cursors or transactions. Implementations
    95  // of this interface should maintain the following invariants:
    96  //
    97  // 1. Each Pin* call should increment the number of references for the connection.
    98  // 2. Each Unpin* call should decrement the number of references for the connection.
    99  // 3. Calls to Close() should be ignored until all resources have unpinned the connection.
   100  type PinnedConnection interface {
   101  	Connection
   102  	PinToCursor() error
   103  	PinToTransaction() error
   104  	UnpinFromCursor() error
   105  	UnpinFromTransaction() error
   106  }
   107  
   108  // The session.LoadBalancedTransactionConnection type is a copy of PinnedConnection that was introduced to avoid
   109  // import cycles. This compile-time assertion ensures that these types remain in sync if the PinnedConnection interface
   110  // is changed in the future.
   111  var _ PinnedConnection = (session.LoadBalancedTransactionConnection)(nil)
   112  
   113  // LocalAddresser is a type that is able to supply its local address
   114  type LocalAddresser interface {
   115  	LocalAddress() address.Address
   116  }
   117  
   118  // Expirable represents an expirable object.
   119  type Expirable interface {
   120  	Expire() error
   121  	Alive() bool
   122  }
   123  
   124  // StreamerConnection represents a Connection that supports streaming wire protocol messages using the moreToCome and
   125  // exhaustAllowed flags.
   126  //
   127  // The SetStreaming and CurrentlyStreaming functions correspond to the moreToCome flag on server responses. If a
   128  // response has moreToCome set, SetStreaming(true) will be called and CurrentlyStreaming() should return true.
   129  //
   130  // CanStream corresponds to the exhaustAllowed flag. The operations layer will set exhaustAllowed on outgoing wire
   131  // messages to inform the server that the driver supports streaming.
   132  type StreamerConnection interface {
   133  	Connection
   134  	SetStreaming(bool)
   135  	CurrentlyStreaming() bool
   136  	SupportsStreaming() bool
   137  }
   138  
   139  // Compressor is an interface used to compress wire messages. If a Connection supports compression
   140  // it should implement this interface as well. The CompressWireMessage method will be called during
   141  // the execution of an operation if the wire message is allowed to be compressed.
   142  type Compressor interface {
   143  	CompressWireMessage(src, dst []byte) ([]byte, error)
   144  }
   145  
   146  // ProcessErrorResult represents the result of a ErrorProcessor.ProcessError() call. Exact values for this type can be
   147  // checked directly (e.g. res == ServerMarkedUnknown), but it is recommended that applications use the ServerChanged()
   148  // function instead.
   149  type ProcessErrorResult int
   150  
   151  const (
   152  	// NoChange indicates that the error did not affect the state of the server.
   153  	NoChange ProcessErrorResult = iota
   154  	// ServerMarkedUnknown indicates that the error only resulted in the server being marked as Unknown.
   155  	ServerMarkedUnknown
   156  	// ConnectionPoolCleared indicates that the error resulted in the server being marked as Unknown and its connection
   157  	// pool being cleared.
   158  	ConnectionPoolCleared
   159  )
   160  
   161  // ErrorProcessor implementations can handle processing errors, which may modify their internal state.
   162  // If this type is implemented by a Server, then Operation.Execute will call it's ProcessError
   163  // method after it decodes a wire message.
   164  type ErrorProcessor interface {
   165  	ProcessError(err error, conn Connection) ProcessErrorResult
   166  }
   167  
   168  // HandshakeInformation contains information extracted from a MongoDB connection handshake. This is a helper type that
   169  // augments description.Server by also tracking server connection ID and authentication-related fields. We use this type
   170  // rather than adding authentication-related fields to description.Server to avoid retaining sensitive information in a
   171  // user-facing type. The server connection ID is stored in this type because unlike description.Server, all handshakes are
   172  // correlated with a single network connection.
   173  type HandshakeInformation struct {
   174  	Description             description.Server
   175  	SpeculativeAuthenticate bsoncore.Document
   176  	ServerConnectionID      *int64
   177  	SaslSupportedMechs      []string
   178  }
   179  
   180  // Handshaker is the interface implemented by types that can perform a MongoDB
   181  // handshake over a provided driver.Connection. This is used during connection
   182  // initialization. Implementations must be goroutine safe.
   183  type Handshaker interface {
   184  	GetHandshakeInformation(context.Context, address.Address, Connection) (HandshakeInformation, error)
   185  	FinishHandshake(context.Context, Connection) error
   186  }
   187  
   188  // SingleServerDeployment is an implementation of Deployment that always returns a single server.
   189  type SingleServerDeployment struct{ Server }
   190  
   191  var _ Deployment = SingleServerDeployment{}
   192  
   193  // SelectServer implements the Deployment interface. This method does not use the
   194  // description.SelectedServer provided and instead returns the embedded Server.
   195  func (ssd SingleServerDeployment) SelectServer(context.Context, description.ServerSelector) (Server, error) {
   196  	return ssd.Server, nil
   197  }
   198  
   199  // Kind implements the Deployment interface. It always returns description.Single.
   200  func (SingleServerDeployment) Kind() description.TopologyKind { return description.Single }
   201  
   202  // SingleConnectionDeployment is an implementation of Deployment that always returns the same Connection. This
   203  // implementation should only be used for connection handshakes and server heartbeats as it does not implement
   204  // ErrorProcessor, which is necessary for application operations.
   205  type SingleConnectionDeployment struct{ C Connection }
   206  
   207  var _ Deployment = SingleConnectionDeployment{}
   208  var _ Server = SingleConnectionDeployment{}
   209  
   210  // SelectServer implements the Deployment interface. This method does not use the
   211  // description.SelectedServer provided and instead returns itself. The Connections returned from the
   212  // Connection method have a no-op Close method.
   213  func (ssd SingleConnectionDeployment) SelectServer(context.Context, description.ServerSelector) (Server, error) {
   214  	return ssd, nil
   215  }
   216  
   217  // Kind implements the Deployment interface. It always returns description.Single.
   218  func (ssd SingleConnectionDeployment) Kind() description.TopologyKind { return description.Single }
   219  
   220  // Connection implements the Server interface. It always returns the embedded connection.
   221  func (ssd SingleConnectionDeployment) Connection(context.Context) (Connection, error) {
   222  	return ssd.C, nil
   223  }
   224  
   225  // RTTMonitor implements the driver.Server interface.
   226  func (ssd SingleConnectionDeployment) RTTMonitor() RTTMonitor {
   227  	return &internal.ZeroRTTMonitor{}
   228  }
   229  
   230  // TODO(GODRIVER-617): We can likely use 1 type for both the Type and the RetryMode by using 2 bits for the mode and 1
   231  // TODO bit for the type. Although in the practical sense, we might not want to do that since the type of retryability
   232  // TODO is tied to the operation itself and isn't going change, e.g. and insert operation will always be a write,
   233  // TODO however some operations are both reads and  writes, for instance aggregate is a read but with a $out parameter
   234  // TODO it's a write.
   235  
   236  // Type specifies whether an operation is a read, write, or unknown.
   237  type Type uint
   238  
   239  // THese are the availables types of Type.
   240  const (
   241  	_ Type = iota
   242  	Write
   243  	Read
   244  )
   245  
   246  // RetryMode specifies the way that retries are handled for retryable operations.
   247  type RetryMode uint
   248  
   249  // These are the modes available for retrying. Note that if Timeout is specified on the Client, the
   250  // operation will automatically retry as many times as possible within the context's deadline
   251  // unless RetryNone is used.
   252  const (
   253  	// RetryNone disables retrying.
   254  	RetryNone RetryMode = iota
   255  	// RetryOnce will enable retrying the entire operation once if Timeout is not specified.
   256  	RetryOnce
   257  	// RetryOncePerCommand will enable retrying each command associated with an operation if Timeout
   258  	// is not specified. For example, if an insert is batch split into 4 commands then each of
   259  	// those commands is eligible for one retry.
   260  	RetryOncePerCommand
   261  	// RetryContext will enable retrying until the context.Context's deadline is exceeded or it is
   262  	// cancelled.
   263  	RetryContext
   264  )
   265  
   266  // Enabled returns if this RetryMode enables retrying.
   267  func (rm RetryMode) Enabled() bool {
   268  	return rm == RetryOnce || rm == RetryOncePerCommand || rm == RetryContext
   269  }