Sobes.tech
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

}