Middle+
Uzdevums: „Vienlaicīga URL apstrāde ar laika ierobežojumu“ Uzrakstiet funkciju fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, kura: 1. Katram URL veic HTTP GET pieprasījumu (var izmantot http.Get). 2. Atgriež map[string]string, kur atslēga ir URL, un vērtība ir atbildes ķermenis (kā virkne) vai tukša virkne kļūdas/laika beigās. 3. Vienlaicīgi tiek izpildīts ne vairāk kā maxParallel pieprasījumu. 4. Kopējais funkcijas darbības laiks nedrīkst pārsniegt timeout. Ja laiks beidzas, visi nepabeigtie pieprasījumi tiek pārtraukti, un funkcija atgriež to, kas ir izdevies. 5. Izmantojiet kontekstu atsaukšanai.
sobes.tech AI
Atbilde no AI
go package main
import ( "context" "io/ioutil" "net/http" "sync" "time" )
func fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()
results := make(map[string]string)
var mu sync.Mutex
sem := make(chan struct{}, maxParallel) // семафор за ограничување на паралелизмот
var wg sync.WaitGroup
for _, url := range urls {
select {
case <-ctx.Done():
break
default:
wg.Add(1)
sem <- struct{}{} // зазема место
go func(u string) {
defer wg.Done()
defer func() { <-sem }() // ослободува место
req, err := http.NewRequestWithContext(ctx, "GET", u, nil)
if err != nil {
mu.Lock()
results[u] = ""
mu.Unlock()
return
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
mu.Lock()
results[u] = ""
mu.Unlock()
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
mu.Lock()
results[u] = ""
mu.Unlock()
return
}
mu.Lock()
results[u] = string(body)
mu.Unlock()
}(url)
}
}
wg.Wait()
return results
}