Sobes.tech
Middle+

Užduotis: „Lygiagretus URL apdorojimas su laiko apribojimu“ Parašykite funkciją fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, kuri: 1. Kiekvienam URL atlieka HTTP GET užklausą (galima naudoti http.Get). 2. Grąžina map[string]string, kur raktas yra URL, o reikšmė – atsakymo turinys (kaip eilutė) arba tuščia eilutė klaidos/timeout atveju. 3. Vienu metu vykdomas ne daugiau kaip maxParallel užklausų. 4. Bendra funkcijos veikimo trukmė neturi viršyti timeout. Jei laikas pasibaigia, visos nepabaigtos užklausos atšaukiamos, ir funkcija grąžina tai, ką pavyko. 5. Naudokite kontekstą atšaukimui.

sobes.tech AI

Atsakymas iš 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) // semaphore for limiting 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

}