Middle+
Вазифа: «Вакыт чегерләмеси менен URL'лердин параллел иштөөсү» Бир функция жазгыла fetchAll(urls []string, maxParallel int, timeout time.Duration) map[string]string, бул: 1. Ар бир URL үчүн HTTP GET суроо жүргүзөт (http.Get колдонулушу мүмкүн). 2. Map[string]string кайтарат, анда ачкыч URL, мааниси жооптун денеси (жол катары) же ката/вакттын аяктоосу учурда бош жол. 3. Бир убакта эң көп дегенде maxParallel суроолор аткарылат. 4. Функциянын жалпы иштөө убактысы timeout'тан ашпашы керек. Эгер убакыт аякса, бардык аяктагыссыз суроолор токтотулат жана функция жетишкендерин кайтарат. 5. Аяктоо үчүн контекстти колдонуу керек.
sobes.tech AI
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
}}