> Как остановить обработку после получения первых двух успешных запросов в Go (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: Ozon

Стек: Go

> Пример ответа

Для остановки обработки после получения первых двух успешных запросов в Go можно использовать контекст с отменой (context.WithCancel) и синхронизацию через каналы. Вот пример:

GO
package main
import (
"context"
"fmt"
"sync"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
results := make(chan int, 2) // буферизированный канал для результатов
var wg sync.WaitGroup
// Запускаем несколько горутин
for i := 1; i <= 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
select {
case <-ctx.Done():
return // остановка, если контекст отменён
default:
// Имитация успешного запроса
fmt.Printf("Горутина %d: запрос выполнен\n", id)
results <- id
}
}(i)
}
// Ждём два успешных результата
successCount := 0
for result := range results {
fmt.Printf("Получен результат от горутины %d\n", result)
successCount++
if successCount >= 2 {
cancel() // отменяем контекст, остальные горутины завершатся
break
}
}
wg.Wait() // дожидаемся завершения всех горутин
close(results)
fmt.Println("Обработка завершена")
}

Пояснение:

  • context.WithCancel создаёт контекст, который можно отменить.
  • Каждая горутина проверяет ctx.Done() перед выполнением - если контекст отменён, она завершается.
  • После получения двух успешных результатов вызывается cancel(), что сигнализирует остальным горутинам остановиться.
  • sync.WaitGroup гарантирует, что главная горутина дождётся завершения всех запущенных процессов.

Этот подход эффективен и безопасен для конкурентной обработки в Go.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью