context.Context

Контекстом называют интерфейс Context из пакета context.

type Context interface {

    // Deadline возвращает время когда этот Context будет отменен.
    Deadline() (deadline time.Time, ok bool)
    
    // Done возвращает канал, который закрывается когда Context отменяется
    Done() <-chan struct{}

    // Err объясняет почему контекст был отменен, после того как закрылся канал Done.
    Err() error

    // Value возвращает значение ассоциированное с ключем или nil.
    Value(key interface{}) interface{}
}

Код почти дословно иллюстрирует, для чего используется контекст:

  • чтобы устанавливать дедлайн исполнения блока кода;
  • оповещать об окончании исполнения блока кода;
  • узнавать причину отмены контекста;
  • получать значения по ключу.

Все методы безопасны для одновременного использования в разных go-рутинах.

Интерфейса достаточно для использования в любых местах, где код может «зависнуть». Это любое сетевое взаимодействие, а также долгие задачи, не выходящие за рамки процесса ОС. Кроме того, контекст можно использовать для неявной передачи параметров в функции.

Хорошей практикой, считается "управлять" горутинами через контекст:

Лучшие практики

  1. context.Background следует использовать только на самом высоком уровне, как корень всех производных контекстов.
  2. context.TODO должен использоваться, когда вы не уверены, что использовать, или если текущая функция будет использовать контекст в будущем.
  3. Отмены контекста рекомендуются, но эти функции могут занимать время, чтобы выполнить очистку и выход.
  4. context.Value следует использовать как можно реже, и его нельзя применять для передачи необязательных параметров. Это делает API непонятным и может привести к ошибкам. Такие значения должны передаваться как аргументы.
  5. Не храните контексты в структуре, передавайте их явно в функциях, предпочтительно в качестве первого аргумента.
  6. Никогда не передавайте nil-контекст в качестве аргумента. Если сомневаетесь, используйте TODO.
  7. Структура Context не имеет метода cancel, потому что только функция, которая порождает контекст, должна его отменять.

Дополнительно