The context Package
In this page:
ctx, cancel := context.WithCancel(parent)
defer cancel()
ctx, cancel := context.WithTimeout(parent, duration)
select {
case <-ctx.Done():
// ctx.Err()
}
Creating a Context with a Timeout
context.WithTimeout creates a context that automatically signals cancellation once the given duration elapses, which is the standard way to bound how long an operation is allowed to run.
Example: Creating a Context with a Timeout
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"context"
"fmt"
"time"
)
// main is where the program starts running
func main() {
// Short declaration: create ctx, cancel and infer the type
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond)
// defer runs this call when the surrounding function returns
defer cancel()
select {
case <-time.After(100 * time.Millisecond):
fmt.Println("work finished")
case <-ctx.Done():
fmt.Println("cancelled:", ctx.Err())
}
}
Login to try C/C++/Java/PHP code in the editor
Manual Cancellation with WithCancel
context.WithCancel returns a context plus a cancel function that, when called, immediately signals every listener watching ctx.Done(), useful for stopping work in response to some other event, not just a timeout.
Example: Manual Cancellation with WithCancel
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"context"
"fmt"
)
// main is where the program starts running
func main() {
// Short declaration: create ctx, cancel and infer the type
ctx, cancel := context.WithCancel(context.Background())
// Start this call in a new goroutine (runs concurrently)
go func() {
// Print the values followed by a newline
fmt.Println("cancelling now")
cancel()
}()
<-ctx.Done()
// Print the values followed by a newline
fmt.Println("received cancellation:", ctx.Err())
}
Login to try C/C++/Java/PHP code in the editor
Passing Context to Functions
Idiomatic Go functions that might need to be cancelled or time out accept a context.Context as their first parameter, letting callers control cancellation without the function needing its own timeout logic baked in.
Example: Passing Context to Functions
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"context"
"fmt"
"time"
)
// Define the function doWork
func doWork(ctx context.Context) {
select {
case <-time.After(50 * time.Millisecond):
fmt.Println("work completed")
case <-ctx.Done():
fmt.Println("work cancelled:", ctx.Err())
}
}
// main is where the program starts running
func main() {
// Short declaration: create ctx, cancel and infer the type
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
// defer runs this call when the surrounding function returns
defer cancel()
doWork(ctx)
}
Login to try C/C++/Java/PHP code in the editor
- Storing a context inside a struct field instead of passing it explicitly as the first parameter of each function, as Go convention expects.
- Forgetting to call the cancel function returned by context.WithCancel/WithTimeout, leaking resources associated with the context.
- Ignoring ctx.Done() inside a long-running goroutine, so it never actually stops even after the context is cancelled.
- context.Context carries cancellation signals and deadlines across API boundaries and goroutines.
- context.WithTimeout and context.WithCancel create a derived context plus a cancel function.
- A goroutine should select on ctx.Done() to notice cancellation and stop its work promptly.
- Convention: context.Context is passed explicitly as a function's first parameter, named ctx.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: