go · level 3 · unit 6 · lesson 2
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
WithTimeout makes a context that cancels itself on time.
context.WithTimeout(parent, 30*time.Millisecond) gives a context that cancels itself once 30 milliseconds have passed. context.WithDeadline(parent, t) does the same at a clock time t. Either way the context has a , and when it passes, Done() closes.
A context that ran out of time reports context.DeadlineExceeded from ctx.Err(). Errors are often wrapped on their way up, so check with errors.Is(err, context.DeadlineExceeded), not ==.
Still write defer cancel(): it frees the timer the moment you are finished, instead of when the deadline arrives.
package main
import (
"context"
"errors"
"fmt"
"time"
)
func slowQuery(ctx context.Context) (string, error) {
select {
case <-time.After(time.Second):
return "42 rows", nil
case <-ctx.Done():
return "", ctx.Err()
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond)
defer cancel()
_, err := slowQuery(ctx)
fmt.Println(err)
fmt.Println(errors.Is(err, context.DeadlineExceeded))
} The query would take a second, but the context gives up after 30 milliseconds.
guess first
Three jobs share one deadline. What prints?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
package main
import (
"context"
"fmt"
"time"
)
func work(ctx context.Context, d time.Duration) error {
select {
case <-time.After(d):
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
defer cancel()
fmt.Println(work(ctx, 10*time.Millisecond))
fmt.Println(work(ctx, time.Second))
fmt.Println(work(ctx, 10*time.Millisecond))
}
your turn
Your turn. Set a fair time limit.
The job takes 20 milliseconds. Choose a timeout in milliseconds that gives it plenty of room, such as 500.
output
press run to see what happens
fix it
The timeout is not recognised. Can you fix it?
output
press run to see what happens
- The error is a deadline error, yet
==says no. What didsalesReportdo to it? %wwraps the deadline error inside a new one, so==compares against the wrapper, not the cause.- Use
errors.Is(err, context.DeadlineExceeded)and add"errors"to the imports.
nailed it
your jobs give up right on time. :D
WithTimeoutandWithDeadlinemake a context that ends by itself.- A missed deadline gives
context.DeadlineExceeded. - Check wrapped errors with
errors.Is, not==.
new words in your collection
- deadline
This lesson isn’t saved. A free account remembers every lesson you finish.