×

go · level 3 · unit 6 · lesson 2

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. 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.