Sobes.tech
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`.

Так достигается параллельная обработка и подсчёт логов по сервисам.