Junior — Senior
Acceleration of execution through parallel requests
livecode
Task condition
It is necessary to refine the Do function so that its execution takes about 10 ms regardless of the number of users passed. Each call to fetchByName simulates a delay of 10 ms. The functions main and fetchByName cannot be changed — all optimization must be implemented inside 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 cannot be changed
func fetchByName(ctx context.Context, userName string) (int, error) {
time.Sleep(10 * time.Millisecond) // simulate network delay
return rand.Int() % 100000, nil
}
// All changes should be made in this function
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
}