В чем разница между `context.Background()` и `context.TODO()`?

Ответ

context.Background() и context.TODO() — это две функции для создания пустого, никогда не отменяемого контекста без значений и дедлайна. С точки зрения реализации они возвращают один и тот же объект, но их семантическое значение и цели использования — разные.

context.Background()

  • Назначение: Использовать как корневой (root) контекст для всех остальных контекстов в приложении.
  • Когда использовать: В main(), в функциях инициализации, в тестах — там, где вы начинаете новую цепочку вызовов, которая должна управляться контекстом.
func main() {
    // Background() используется как отправная точка для всех контекстов в приложении.
    ctx := context.Background()

    // Создаем дочерний контекст с таймаутом
    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()

    doSomething(ctx)
}

context.TODO()

  • Назначение: Использовать как временную заглушку (placeholder), когда вы не уверены, какой контекст использовать, или когда функция должна принимать контекст, но он еще не "проброшен" из вышестоящего кода.
  • Когда использовать: В процессе рефакторинга или когда API, который вы вызываете, требует context.Context, но у вас его пока нет. Использование TODO() — это явный сигнал для вас и других разработчиков (а также для статических анализаторов), что этот код нужно доработать.
// Представим, что мы рефакторим старую функцию, которая не принимала контекст.
func processRequest(userID int) {
    // API клиента теперь требует контекст, но мы еще не пробросили его сюда.
    // Используем TODO() как временное решение.
    // TODO: Пробросить реальный контекст в processRequest.
    ctx := context.TODO()

    user, err := userAPI.GetUser(ctx, userID)
    // ...
}

Сводка:

КонтекстНазначениеПример использования
context.Background()Корневой контекст. Явно указывает, что это начало цепочки.main(), инициализация сервиса.
context.TODO()Заглушка. Явно указывает на недоработку.В процессе рефакторинга, когда контекст еще не доступен.

Вывод: Используйте Background() для старта новых процессов и TODO() как временную меру, которую необходимо устранить до попадания кода в продакшн.