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
}