Junior
What is a context in Go?
sobes.tech AI
Answer from AI
The (context.Context) in Go is an object that carries deadlines, cancellation signals, and request-specific data. It is used to manage the lifecycle of goroutines and pass information between them during the execution of a single request/operation.
Main characteristics:
- Thread-safe: Can be safely passed between goroutines.
- Immutable: Once created, a
Contextcannot be changed. Derivative contexts are created based on the parent. - Hierarchical: Contexts form a tree with a root (
context.Background()orcontext.TODO()). Cancelling a parent context cancels all its children.
Main functions of the context package:
context.Background(): An empty context, usually used in main functions, top-level requests, or testing. Never canceled.context.TODO(): Also an empty context. Used as a placeholder when it is unknown which context to use, or if the context functionality is not yet implemented.context.WithCancel(parent Context): Returns a new child context and a cancel function. Calling the cancel function cancels this context and all its children.context.WithDeadline(parent Context, deadline time.Time): Returns a child context that automatically cancels when the specified time is reached. Also returns a cancel function for manual cancellation.context.WithTimeout(parent Context, timeout time.Duration): Same asWithDeadline, but with a duration.context.WithValue(parent Context, key, val interface{}): Returns a child context with an assigned value for the key.
Usage:
- Operation cancellation: For example, timeout of an HTTP request or interruption of a long operation.
- Data passing: For example, request ID for logging, authentication information.
Example of using context.WithTimeout:
package main
import (
"context"
"fmt"
"time"
)
func longRunningOperation(ctx context.Context, resultChan chan string) {
select {
case <-time.After(3 * time.Second):
// Operation completed successfully
resultChan <- "Operation completed"
case <-ctx.Done():
// Context was canceled
err := ctx.Err() // Get the reason for cancellation
resultChan <- fmt.Sprintf("Operation cancelled: %v", err)
}
}
func main() {
// Create a context with a 2-second timeout
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Ensure cancel is called
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Wait for result or cancellation
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Main context done: %v\n", ctx.Err())
}
// Wait a bit to let the goroutine finish if it was canceled
time.Sleep(1 * time.Second)
}
In this example, longRunningOperation checks the context for cancellation. If the main context's timeout (2 seconds) expires before the operation (3 seconds) completes, the goroutine receives a cancellation signal via ctx.Done() and terminates.