Sobes.tech
Middle+

Vazifa: «Vaqt cheklov bilan URL-larni parallel tarzda ishlash» Bir funktsiya yozing fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, bu: 1. Har bir URL uchun HTTP GET so'rovini bajaradi (http.Get ishlatilishi mumkin). 2. Map[string]string qaytaradi, unda kalit URL, qiymat esa javob matni (matn sifatida) yoki xato/timeout bo'lsa bo'sh satr. 3. Bir vaqtning o'zida maksimal maxParallel so'rovlar bajariladi. 4. Funktsiyaning umumiy ishlash vaqti timeout dan oshmasligi kerak. Agar vaqt tugasa, barcha bajarilmayotgan so'rovlar bekor qilinadi va funksiya erishgan natijasini qaytaradi. 5. Bekor qilish uchun kontekstdan foydalaning.

sobes.tech AI

AIdan javob

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

}