You can manage in-progress operations by using Go context.Context
. A Context
is a standard Go data value that can report whether the overall operation it represents has been cancelled and is no longer needed. By passing a context.Context
across function calls and services in your application, those can stop working early and return an error when their processing is no longer needed. For more about Context
, see Go Concurrency Patterns: Context.
For example, you might want to:
Many APIs for Go developers include methods that take a Context
argument, making it easier for you to use Context
throughout your application.
You can use a Context
to set a timeout or deadline after which an operation will be cancelled. To derive a Context
with a timeout or deadline, call context.WithTimeout
or context.WithDeadline
.
Code in the following timeout example derives a Context
and passes it into the sql.DB
QueryContext
method.
func QueryWithTimeout(ctx context.Context) { // Create a Context with a timeout. queryCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() // Pass the timeout Context with a query. rows, err := db.QueryContext(queryCtx, "SELECT * FROM album") if err != nil { log.Fatal(err) } defer rows.Close() // Handle returned rows. }
When one context is derived from an outer context, as queryCtx
is derived from ctx
in this example, if the outer context is cancelled, then the derived context is automatically cancelled as well. For example, in HTTP servers, the http.Request.Context
method returns a context associated with the request. That context is cancelled if the HTTP client disconnects or cancels the HTTP request (possible in HTTP/2). Passing an HTTP request’s context to QueryWithTimeout
above would cause the database query to stop early either if the overall HTTP request was cancelled or if the query took more than five seconds.
Note: Always defer a call to the cancel
function that's returned when you create a new Context
with a timeout or deadline. This releases resources held by the new Context
when the containing function exits. It also cancels queryCtx
, but by the time the function returns, nothing should be using queryCtx
anymore.