📌 Как устроены контексты в Go?



💬 Спрашивают в 33% собеседований



Контексты (context.Context) представляют собой интерфейс, который используется для передачи мета-данных, управления сроками действия и отменой операций в иерархии вызовов функций. Основная цель контекста — обеспечение способа для остановки выполнения программы (например, запросов или подпроцессов) по требованию. Это особенно полезно в сетевых приложениях, где вам может потребоваться прервать выполнение операции, которая больше не требуется или занимает слишком много времени.



Ключевые особенности:



1️⃣ Пропаганда по горутинам: Контекст предназначен для безопасной передачи по горутинам, что означает, что он может быть передан между различными частями вашей программы, выполняющимися в разных горутинах.



2️⃣ Отмена операций: Контекст может быть отменен, что автоматически сигнализирует всем получателям этого контекста о необходимости остановить свою работу. Это обеспечивается через канал, который закрывается, когда контекст отменяется.



3️⃣ Сроки выполнения: Контекст может иметь установленный таймаут или дедлайн, после достижения которого он автоматически отменяется.



4️⃣ Значения: Контексты могут нести значения — пары ключ-значение, которые можно устанавливать и получать. Эти значения обычно используются для передачи данных, специфичных для запроса, таких как идентификаторы сессий или токены авторизации.



🤔 Создание и использование контекста



Есть несколько способов создания контекста, включая базовые функции из пакета context:



context.Background(): Возвращает пустой контекст, который никогда не отменяется. Обычно используется в основной функции и при инициализации.



context.TODO(): Используется для указания, что должен быть предоставлен подходящий контекст. Обычно применяется в разработке и при рефакторинге.



context.WithCancel(parent Context) (ctx Context, cancel CancelFunc): Создает новый контекст с возможностью отмены.



context.WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc): Создает контекст, который автоматически отменяется в указанный deadline.



context.WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc): Аналогичен WithDeadline, но устанавливает время жизни контекста на основе заданного таймаута.



🤔 Пример:

func operation1(ctx context.Context) {

select {

case <-time.After(5 * time.Second):

fmt.Println("operation1 completed")

case <-ctx.Done():

fmt.Println("operation1 cancelled")

}

}



func main() {

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)

defer cancel()



go operation1(ctx)



// Дожидаемся завершения или отмены операции

<-ctx.Done()

if err := ctx.Err(); err != nil {

fmt.Println("main:", err)

}

}




В этом примере функция operation1 прерывается, если контекст отменяется до истечения времени ожидания в 5 секунд.



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



🔥 ТОП ВОПРОСОВ С СОБЕСОВ



🔒 База собесов | 🔒 База тестовых