go func FetchAll(ctx context.Context, urls []string, concurrency int) ([]Result, error) { type resultWithError struct { res Result err error }
// Есть сеть банковских терминалов. Нужно собирать показания отклика нахождения в сети. Терминалы расположены по все стране.
go func FetchAll(ctx context.Context, urls []string, concurrency int) ([]Result, error) { type resultWithError struct { res Result err error }
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
// Есть сеть банковских терминалов. Нужно собирать показания отклика нахождения в сети. Терминалы расположены по все стране.
// Написать функцию, которая получает URL из входящего списка ([]string{"[link] "[link] "[link] и т.д.}) // ответ выводить в stdout в отдельной строке "url: %s, code: %s"
func check(urls []string) {}
Ответ
go func FetchAll(ctx context.Context, urls []string, concurrency int) ([]Result, error) { type resultWithError struct { res Result err error }
results := make([]Result, len(urls))
ch := make(chan resultWithError)
sem := make(chan struct{}, concurrency) // ограничение по concurrency
for i, url := range urls {
select {
case <-ctx.Done():
return nil, ctx.Err()
case sem <- struct{}{}: // занять слот
}
go func(i int, url string) {
defer func() { <-sem }() // освободить слот
res, err := Fetch(ctx, url) // предполагается функция Fetch
ch <- resultWithError{res, err}
}(i, url)
}
for i := 0; i < len(urls); i++ {
select {
case <-ctx.Done():
return nil, ctx.Err()
case r := <-ch:
if r.err != nil {
return nil, r.err
}
results[i] = r.res
}
}
return results, nil
}
Этот код запускает до `concurrency` горутин для параллельного получения данных по URL, используя контекст для отмены. Результаты собираются в срез `results`.