Middle+
Ülesanne: „Paralleelne URL-de töötlemine ajapiiranguga“ Kirjutage funktsioon fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, mis: 1. Teeb iga URL jaoks HTTP GET-päringu (võib kasutada http.Get). 2. Tagastab kaardi[string]string, kus võti on URL ja väärtus on vastuse keha (stringina) või tühi string vea/aegumise korral. 3. Samal ajal tehakse mitte rohkem kui maxParallel päringut. 4. Funktsiooni koguaeg ei tohi ületada timeouti. Kui aeg lõpeb, tühistatakse kõik lõpetamata päringud ja funktsioon tagastab selle, mis õnnestus. 5. Kasutage tühistamiseks konteksti.
sobes.tech AI
Vastus AI-lt
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) // semaphore to limit parallelism
var wg sync.WaitGroup
for _, url := range urls {
select {
case <-ctx.Done():
break
default:
wg.Add(1)
sem <- struct{}{} // reserve a slot
go func(u string) {
defer wg.Done()
defer func() { <-sem }() // release the slot
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
}