Back to questions
Senior
2
Реализуй Worker Pool для обработки логов: читать логи из канала, обрабатывать параллельно, подсчитать количество логов по каждому сервису, вернуть map[serviceName]count.
Companies where asked
А7
Answer from AI
sobes.tech AI
go package main
import ( "fmt" "sync" )
type Log struct { Service string Message string }
func worker(id int, logs <-chan Log, counts chan<- map[string]int, wg *sync.WaitGroup) { defer wg.Done() localCount := make(map[string]int) for log := range logs { localCount[log.Service]++ } counts <- localCount }
func mergeCounts(countsList []map[string]int) map[string]int { result := make(map[string]int) for _, counts := range countsList { for service, count := range counts { result[service] += count } } return result }
func main() { logChan := make(chan Log) countsChan := make(chan map[string]int) var wg sync.WaitGroup nWorkers := 5
// Запускаем воркеров
for i := 0; i < nWorkers; i++ {
wg.Add(1)
go worker(i, logChan, countsChan, &wg)
}
// Отправляем логи в канал (пример)
go func() {
logs := []Log{
{"serviceA", "message1"},
{"serviceB", "message2"},
{"serviceA", "message3"},
{"serviceC", "message4"},
}
for _, log := range logs {
logChan <- log
}
close(logChan)
}()
// Ждём завершения воркеров
go func() {
wg.Wait()
close(countsChan)
}()
// Собираем результаты
var countsList []map[string]int
for c := range countsChan {
countsList = append(countsList, c)
}
finalCounts := mergeCounts(countsList)
fmt.Println(finalCounts)
}
В этом примере:
- Логи поступают в канал `logChan`.
- Несколько воркеров параллельно читают логи, подсчитывают количество по сервисам локально.
- По завершении работы каждый воркер отправляет свой локальный подсчёт в канал `countsChan`.
- Основной поток собирает все локальные подсчёты и объединяет их в итоговую карту `map[string]int`.
Так достигается параллельная обработка и подсчёт логов по сервисам.