Загрузчик профилей берёт список id, раздаёт их пяти воркерам и собирает ответ. Каждый профиль нужно получить через fetchFromRemoteAPI (имитация медленного запроса к API) и положить в кэш, чтобы не ходить в API за одним id дважды. Код компилируется, но под -race падает. Найдите ошибки и исправьте их в starter.go.
type UserProfile struct {
ID int
Name string
}
func NewUserFetcher() *UserFetcher
// FetchUsersData возвращает по одному профилю на каждый id из userIDs.
// Повторы в запросе дают повторы в ответе.
func (uf *UserFetcher) FetchUsersData(userIDs []int) []UserProfile
Что должно получиться:
- в ответе ровно
len(userIDs) профилей, и каждый id встречается столько раз, сколько он был в запросе;
- у профиля с
ID: 7 поле Name равно "User7";
- нет гонок данных, в том числе вокруг кэша;
- число воркеров остаётся пятью, на каждый id новая горутина не создаётся;
- если два воркера одновременно оказались без профиля в кэше, к API должен уйти один запрос, второй воркер дожидается его результата.
Пример. Запрос [3, 5, 3] вернёт три профиля: User3, User5, User3, и fetchFromRemoteAPI(3) вызывается один раз.
Сам запрос выполняет функция remoteAPI из скрытого support.go: она считает обращения и одновременные вызовы. Метод fetchFromRemoteAPI в starter.go просто вызывает её, его менять не нужно.
Тесты проверяют количество профилей, имена и то, сколько раз встречается каждый id (порядок профилей не проверяется). Кроме того, они считают обращения к API: на каждый id ровно один запрос, в том числе когда пять воркеров одновременно получили одинаковый id и когда FetchUsersData вызывают повторно на том же загрузчике. Одновременных запросов к API не больше пяти, но больше одного.