Sobes.tech
Middle+

Tâche : « Traitement parallèle des URL avec limite de temps » Écrivez une fonction fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, qui : 1. Pour chaque URL, effectue une requête HTTP GET (peut utiliser http.Get). 2. Retourne un map[string]string, où la clé est l'URL, et la valeur est le corps de la réponse (en chaîne) ou une chaîne vide en cas d'erreur/timeout. 3. Au maximum, maxParallel requêtes sont exécutées simultanément. 4. La durée totale de la fonction ne doit pas dépasser timeout. Si le délai est écoulé, toutes les requêtes non terminées sont annulées, et la fonction retourne ce qu'elle a pu. 5. Utilisez le contexte pour l'annulation.

sobes.tech IA

Réponse de l'IA

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) // sémaphore pour limiter le parallélisme
var wg sync.WaitGroup

for _, url := range urls {
	select {
	case <-ctx.Done():
		break
	default:
		wg.Add(1)
		sem <- struct{}{} // réserver une place

		go func(u string) {
			defer wg.Done()
			defer func() { <-sem }() // libérer la place

			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

}