This is a follow up of my first context post.
Another typical usage of context is to limit the duration of a particular process. The context construct provides two methods for that. First, WithTimeout()
where we pass a context and the duration of the timer. The second option is WithDeadline()
where we pass the exact Time.time
we want the computation to stop. Both methods return the new context and a cancellation function we can use to cancel the context immediately.
Here is an example (with comments) where we have a goroutine that simulates a computation and another goroutine that implements the timeout.
package main
import (
"context"
"log"
"time"
)
const (
defaultTaskD int = 5
defaultTO int = 10
)
func main() {
// compute the duration given the defaults
taskDuration := time.Duration(defaultTaskD) * time.Second
toDuration := time.Duration(defaultTO) * time.Second
// Set a context with timeout
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, toDuration)
defer cancel()
// We need a channel to send the results of our computations
ch := make(chan int)
// The goroutine for our task. Resturn 42 when done
go func() {
log.Printf("task starts running; taskDuration=%s timeout=%s", taskDuration, toDuration)
time.Sleep(taskDuration)
ch <- 42
}()
// If toDuration has passed, use the cancellation function
go func() {
time.Sleep(toDuration)
cancel()
}()
// Wait for either a cancelation or the result of our computation
select {
case result := <-ch:
log.Printf("task completed fine. result=%d\n", result)
case <-ctx.Done():
log.Println("task timed out")
}
}