Middle+
Aufgabe: «Parallele Verarbeitung von URLs mit Zeitlimit» Schreiben Sie eine Funktion fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, die: 1. Für jede URL eine HTTP GET-Anfrage durchführt (kann http.Get sein). 2. Gibt eine map[string]string zurück, wobei der Schlüssel die URL ist und der Wert der Antwortkörper (als String) oder ein leerer String bei Fehler/Timeout. 3. Nicht mehr als maxParallel Anfragen gleichzeitig ausgeführt werden. 4. Die gesamte Laufzeit der Funktion darf timeout nicht überschreiten. Wenn die Zeit abläuft, werden alle nicht abgeschlossenen Anfragen abgebrochen, und die Funktion gibt das zurück, was sie geschafft hat. 5. Verwenden Sie den Kontext zur Abbruchsteuerung.
sobes.tech KI
Antwort von 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) // semáforo para limitar o paralelismo
var wg sync.WaitGroup
for _, url := range urls {
select {
case <-ctx.Done():
break
default:
wg.Add(1)
sem <- struct{}{} // reservar um espaço
go func(u string) {
defer wg.Done()
defer func() { <-sem }() // libertar o espaço
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
}