Context
On this page
Overview
The Go driver uses the context package from the Go standard library to allow applications to signal timeouts and cancellations for any blocking method call. A blocking method relies on an external event, such as a network input or output, to proceed with its task.
An example of a blocking method is the InsertOne()
method. If you want to perform an insert operation on a Collection
within 10 seconds, you can use a Context with a timeout. If the
operation doesn't complete within the timeout, the method returns
an error.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client.Database("db").Collection("items").InsertOne(ctx, bson.D{{"x",1}})
If the Context passed into an operation does not have a deadline, you
can set a Timeout
option on your Client
and the operation
derives the timeout specification from this setting. To learn more
about using the single timeout setting, see the
Single Timeout Setting in the Connection Options guide.
Expiration
The driver considers a Context expired when an operation exceeds its
timeout or is canceled. The driver checks the Context expiration with
the Done()
method.
The following sections describe when and how the driver checks for expiration.
Server Selection
The driver might block a method call if it can't select a server for an operation.
In this scenario, the driver loops until it finds a server to use for the
operation. After each iteration, the driver returns a server selection
timeout error if the Context expired or the selection process took
longer than the serverSelectionTimeoutMS
setting.
To learn more about how the driver selects a server, see the Server Selection Algorithm.
Connection Checkout
The driver might block a method call if there are no available connections to check out.
After selecting a server, the driver tries to check out a connection from the server's connection pool. If the Context expires while checking out a connection, the method returns a timeout error.
Connection Establishment
The driver might block a method call if it must create a new connection.
When the driver creates a new connection to perform an operation, the Context sets a timeout for the establishment process. The driver sets the timeout to either the Context expiration or connection timeout, whichever is shorter.
The following example sets the connection timeout to 1 second and the Context deadline to 2 seconds. Because the connection timeout is shorter, the establishment process expires after 1 second.
opts := options.Client() opts.SetConnectTimeout(1*time.Second) client, err := mongo.Connect(opts) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() client.Database("<db>").Collection("<collection>").InsertOne(ctx, bson.D{{"x",1}})
Socket Read and Write
When the driver retrieves a connection for an operation, it sets the socket’s read or write deadline to either the Context deadline or socket timeout, whichever is shorter.
If you cancel the Context after the execution of the Read()
or
Write()
method but before its deadline, the behavior of the driver
differs based on version.
The driver generates a separate goroutine to listen for Context
cancellation when the Read()
or Write()
method is in progress.
If the goroutine detects a cancellation, it closes the connection. The
pending Read()
or Write()
method returns an error which the
driver overwrites with the context.Canceled
error.
Important
In versions prior to 1.5.0, the driver doesn't detect the Context
cancellation and waits for the Read()
or Write()
method to
return.