WithTimeout
- Go course
- Intermediate
- Lesson 31/80
- 4 min
Learn time-bounded context with WithTimeout.
WithTimeout
context.WithTimeout(parent, d) creates a context that cancels itself when the duration passes. It prevents endless waits in network requests and database queries:
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
// with no response in 2 seconds, err: context deadline exceededWhy defer cancel is still needed
Even though the context cancels itself when time runs out, if the work finishes early the internal timer stays in memory until it fires. defer cancel() stops the timer right away. To tell whether an error came from the timeout, use errors.Is(err, context.DeadlineExceeded).
Practice A slow operation
Write yavas(ctx context.Context) error: it waits with select on time.After(100*time.Millisecond) or ctx.Done() and returns ctx.Err() on cancellation. Call it with a 10 ms timeout and print with errors.Is whether the error is DeadlineExceeded.
Starter code
package main
import (
"context"
"errors"
"fmt"
"time"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"context"
"errors"
"fmt"
"time"
)
func yavas(ctx context.Context) error {
select {
case <-time.After(100 * time.Millisecond):
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()
err := yavas(ctx)
fmt.Println(errors.Is(err, context.DeadlineExceeded))
}Expected output
true
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 If the parent ends in 1 second, when is <code>WithTimeout(parent, 5*time.Second)</code> cancelled?
- In 1 second (with the parent) Correct answer
- In 5 seconds
- In 6 seconds
- Never
Explanation: A child context can't outlive its parent; the effective deadline is the earlier of the two.
2 Timeout error
if errors.Is(err, context.____) {
log.Println("zaman aşımı")
}
if errors.Is(err, context.DeadlineExceeded) {
log.Println("zaman aşımı")
}
Explanation: DeadlineExceeded is the error of a context cancelled because time ran out.
3 Error and cause
| Term | Meaning |
|---|---|
context.Canceled |
cancel() was called |
context.DeadlineExceeded |
Time ran out |
NewRequestWithContext |
Binds ctx to a request |
defer cancel() |
Stops the timer |