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

}