Junior — Senior
Ускорение выполнения через параллельные запросы
livecode
Vazifa holati
Необходимо доработать функцию Do так, чтобы её выполнение занимало около 10 мс независимо от количества переданных пользователей. Каждый вызов fetchByName имитирует задержку в 10 мс. Функции main и fetchByName менять нельзя – вся оптимизация должна быть реализована внутри Do.
package main
import (
"context"
"fmt"
"math/rand"
"sync"
"time"
)
type User struct {
Name string
}
func main() {
fmt.Println(Do(context.Background(), []User{{"aaa"}, {"bbb"}, {"ccc"}, {"ddd"}, {"eeee"}}))
}
// fetchByName изменять нельзя
func fetchByName(ctx context.Context, userName string) (int, error) {
time.Sleep(10 * time.Millisecond) // имитация сетевого похода
return rand.Int() % 100000, nil
}
// все изменения должны происходить в этой функции
func Do(ctx context.Context, users []User) (map[string]int, error) {
result := make(map[string]int)
var mu sync.Mutex
var wg sync.WaitGroup
errCh := make(chan error, 1)
for _, usr := range users {
wg.Add(1)
go func(u User) {
defer wg.Done()
id, err := fetchByName(ctx, u.Name)
if err != nil {
select {
case errCh <- err:
default:
}
return
}
mu.Lock()
result[u.Name] = id
mu.Unlock()
}(usr)
}
wg.Wait()
close(errCh)
if err, ok := <-errCh; ok {
return result, err
}
return result, nil
}