liveBook · Manning

Context

As explained in Learn Go with Pocket-Sized Projects

context.Context is a Go interface carrying cancellation signals, deadlines, and request-scoped values across function and service boundaries.

A gRPC request may pass through an endpoint, business logic, and a repository before it finishes. Pass its context.Context along that path so a deadline or cancellation can reach work started on the request’s behalf. Generated gRPC endpoint signatures already provide an incoming context; use it rather than starting over with a new one. section 10.3.3 section 10.6.2

context.Context is an interface with four methods: Deadline reports an expiration time, if set; Done returns a channel closed when the context ends; Err reports why it ended, or nil while it remains active; and Value retrieves an attached value. You normally use implementations supplied by Go’s context package, not implement the interface yourself. Check <-ctx.Done() to stop waiting, then use ctx.Err() to report the reason. section 10.6.1 section 10.6.3

Keep context ownership and propagation predictable:

  • Create an application’s parent context with context.Background() in main. A function that receives a context should pass it onward or derive a child, not replace it with Background() or TODO(). section 10.6.2
  • Accept context.Context as the first parameter, conventionally named ctx. Pass it explicitly instead of storing it in a struct. section 10.6.2
  • Use context.WithDeadline for a specific expiration time or context.WithTimeout for a duration. Give separate remote calls their own child contexts when their time limits need separate control. section 10.6.2 section 10.6.3
  • Reserve context values for noncritical identifiers, such as request or monitoring IDs. Pass business inputs as explicit parameters so a function’s requirements remain visible. section 10.6.1

Bound a repository call

After validating a habit, derive a context for its database operation: dbCtx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) defer cancel() err := db.Add(dbCtx, h) The repository receives the child context, not a fresh background context. It must observe cancellation for the limit to interrupt its work—for example, by selecting on <-dbCtx.Done() and returning dbCtx.Err(). Choose a timeout that accounts for the latency of the operation. section 10.6.3 section 10.3.3

Listing 10.32 create_test.go: Testing the timeout
func TestCreate(t *testing.T) {
    // ...
    "db timeout": {
        db: func(ctl *minimock.Controller) *mocks.HabitCreatorMock {
            db := mocks.NewHabitCreatorMock(ctl)
            db.AddMock.Set(
                func(ctx context.Context, habit habit.Habit) error {
                    select {
                    // This tick is longer than a database call
                    case <-time.Tick(2 * time.Second):
                        return nil
                    case <-ctx.Done():
                        return ctx.Err()
                    }
                })
            return db
        },
        expectedErr: context.DeadlineExceeded, #1
    },

A timeout test makes the mocked repository wait longer than the 100 ms limit, then expects context.DeadlineExceeded. When an exact child context is unpredictable, minimock.AnyContext can match the argument in ordinary mock expectations; that match alone does not test the timeout. section 10.6.3

How Learn Go with Pocket-Sized Projects covers it

How deep it goes
Defines the four interface methods and works through child-context creation, timeout handling, and tests without implementing the interface.
Examples
Uses a habit-creation repository call with a 100 ms timeout and a slow mock expecting context.DeadlineExceeded.
What it assumes
Assumes familiarity with Go functions, channels, and tests while defining context.Context and explaining its methods.
What you can do after
Apply it via Go’s context package to propagate request cancellation and test bounded repository calls.
How it connects
Connects gRPC, repository interfaces, deadlines, cancellation channels, and dependency mocking.

Also explained in

Compare how 7 books explain context →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Go with Pocket-Sized Projects. The section links point to the parts of the book it draws on.