Все вопросы

34 Конкурентность

Зачем context.Context?

context несёт отмену и дедлайн сквозь цепочку вызовов. Первым аргументом функции, которая может ждать, ставят ctx context.Context. Отмена родителя отменяет всех детей. defer cancel() вызывают сразу после создания, чтобы освободить таймер.

ctx.Err() после отмены — это context.Canceled или context.DeadlineExceeded. Значения в контекст кладут редко и только данные запроса вроде идентификатора трассировки, не бизнес-объекты и не соединение с базой.

Контекст не хранят в структуре надолго. Его передают аргументом.

Пример

Go

работа обрывается по таймауту

package main

import (
    "context"
    "fmt"
    "time"
)

func work(ctx context.Context) error {
    select {
    case <-time.After(time.Second):
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
    defer cancel()

    fmt.Println(work(ctx))
}