Конструирование пула воркеров

Пул должен владеть фиксированными работниками и очередью заданий. В main нужно дождаться его завершения после окончания генератора, иначе процесс выйдет с незавершёнными запросами.

Короткий ответ

Что ответить на собеседовании

Пул должен владеть фиксированными работниками и очередью заданий. В main нужно дождаться его завершения после окончания генератора, иначе процесс выйдет с незавершёнными запросами.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо построить механизм, который:

  • Запускает не более трёх воркеров одновременно;
  • Делает HTTP GET запросы к каждому адресу из предоставленного списка;
  • Ограничивает количество параллельных запросов, чтобы не перегрузить систему.
package main 
        
import {
    "log"
        }
        
        
func main() {
    pool :=makePool(3)
    for url := range generateUrls(5){
        log.Printf("=> Запуск, %s", url)
        pool.Dowork(url)        
    }
}        

Ответ

Пул должен владеть фиксированными работниками и очередью заданий. В main нужно дождаться его завершения после окончания генератора, иначе процесс выйдет с незавершёнными запросами.

Исправьте import на круглые скобки и добавьте net/http, sync, time. Минимальная реализация:

type Pool struct {
    jobs chan string
    wg sync.WaitGroup
    client *http.Client
}
func makePool(n int) *Pool {
    if n < 1 { panic("invalid workers") }
    p := &Pool{jobs: make(chan string), client: &http.Client{Timeout: 5*time.Second}}
    for i := 0; i < n; i++ {
        p.wg.Add(1)
        go func() {
            defer p.wg.Done()
            for url := range p.jobs {
                resp, err := p.client.Get(url)
                if err != nil { log.Printf("%s: %v", url, err); continue }
                log.Printf("%s: %d", url, resp.StatusCode)
                resp.Body.Close()
            }
        }()
    }
    return p
}
func (p *Pool) Dowork(url string) { p.jobs <- url }
func (p *Pool) Close() { close(p.jobs); p.wg.Wait() }

Сразу после makePool(3) поставьте defer pool.Close(). Close — однократная операция владельца после завершения всех отправок; конкурентно с Dowork его не вызывают. generateUrls должна закрыть выходной канал.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее