Перейти к основному содержимому

Практика: Context в Go


Онлайн редактор кода для Go

Здесь вы можете попробовать свои силы в программировании на языке Go. Для этого мы предоставляем вам онлайн редактор кода, в котором вы можете написать свой код и запустить его.


❗️ При обновлении страницы код пропадёт, по этому, сохраните свой код куда-нибудь, если он важный.

Задание 1 — Долгая вычислительная задача с таймаутом

Задание 1: Долгая вычислительная задача

⏱️ Примерное время: 10-15 минут

Напиши функцию LongCompute(ctx context.Context, n int) (int64, error). Имитируй тяжёлую работу (сумма 0..n с sleep). Если контекст отменён — верни ctx.Err(). В main используй WithTimeout(2s).


Требования:

  • цикл for i := 0; i < n; i++ { sum += i; select { case <-ctx.Done(): return 0, ctx.Err() ... } }
  • в main: ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
  • defer cancel()
  • выведи "Превышен таймаут" или результат

Пример вывода:

Запускаем вычисление...
Превышен таймаут: context deadline exceeded

Задание 2 — Отмена параллельных задач по кнопке

Задание 2: Отмена параллельных задач

⏱️ Примерное время: 15-20 минут

Запусти 5 горутин, каждая считает простые числа до 1 млн. Через 3 секунды в main вызови cancel(). Горутины должны остановиться.


Требования:

  • ctx, cancel := context.WithCancel(context.Background())
  • каждая горутина: for i := 2; i < limit; i++ { if IsPrime(i) { select { case <-ctx.Done(): return; default: count++ } } }
  • через time.Sleep(3 * time.Second)cancel()
  • выведи количество найденных простых чисел до отмены

Пример вывода:

Воркер 1: нашёл 78498 простых до отмены
Отмена получена: context canceled

Задание 3 — Параллельный парсинг файлов с errgroup

Задание 3: Параллельный парсинг файлов

⏱️ Примерное время: 20-25 минут

Дан слайс имён файлов. Запусти горутины для чтения каждого файла. Собери первую ошибку через errgroup.WithContext.


Требования:

  • g, ctx := errgroup.WithContext(context.Background())
  • ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
  • defer cancel()
  • каждая горутина: os.ReadFile, если ошибка — return err
  • в конце: if err := g.Wait(); err != nil { ... }

Пример вывода:

Успешно прочитано 5 файлов
Ошибка: open data_missing.txt: no such file

Задание 4 — Передача trace_id через WithValue

Задание 4: Trace ID через контекст

⏱️ Примерное время: 15-20 минут

Создай функцию ProcessData(ctx context.Context, data string) error. Клади trace_id в контекст и доставай в вложенных функциях.


Требования:

  • type traceKey string; const TraceIDKey traceKey = "trace_id"
  • ctx = context.WithValue(ctx, TraceIDKey, id)
  • в вложенной функции: id := ctx.Value(TraceIDKey).(string)
  • логируй через slog: "Обработка", "trace_id", id

Пример вывода:

level=INFO msg="Начало обработки" trace_id=abc123
level=INFO msg="Данные обработаны" trace_id=abc123

Задание 5 — Итоговое: Параллельный поиск + таймаут + trace_id

Задание 5: Параллельный поиск с trace_id и таймаутом (итоговое)

⏱️ Примерное время: 35-50 минут

Дан trace_id и слайс файлов. Запусти параллельный поиск слова (errgroup + WithTimeout 8s). Передай trace_id через WithValue.


Требования:

  • g, ctx := errgroup.WithContext(context.Background())
  • ctx = context.WithTimeout(ctx, 8*time.Second)
  • ctx = context.WithValue(ctx, TraceIDKey, trace_id)
  • каждая горутина: чтение файла + поиск слова
  • логируй: "Поиск", "trace_id", trace_id, "file", filename
  • если таймаут — первая ошибка DeadlineExceeded

Пример вывода:

level=INFO msg="Начало поиска" trace_id=abc123
level=INFO msg="Найдено" trace_id=abc123 file=log1.txt
level=WARN msg="Превышен таймаут" trace_id=abc123
подсказка

Context — это не просто таймаут. Это способ сделать твой код вежливым, отзывчивым и безопасным.
Всегда передавай ctx первым параметром, проверяй Done() и используй errgroup — это стандарт де-факто в 2026 году.