Sobes.tech
Middle+

Ülesanne: „Paralleelne URL-de töötlemine ajapiiranguga“ Kirjutage funktsioon fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, mis: 1. Teeb iga URL jaoks HTTP GET-päringu (võib kasutada http.Get). 2. Tagastab kaardi[string]string, kus võti on URL ja väärtus on vastuse keha (stringina) või tühi string vea/aegumise korral. 3. Samal ajal tehakse mitte rohkem kui maxParallel päringut. 4. Funktsiooni koguaeg ei tohi ületada timeouti. Kui aeg lõpeb, tühistatakse kõik lõpetamata päringud ja funktsioon tagastab selle, mis õnnestus. 5. Kasutage tühistamiseks konteksti.

sobes.tech AI

Vastus AI-lt

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 to limit 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

}