fetchRepoStars fetches stargazer counts for each unique repository in the result set, using bounded concurrency.
(client *api.Client, host string, skills []skillResult)
| 894 | // fetchRepoStars fetches stargazer counts for each unique repository in |
| 895 | // the result set, using bounded concurrency. |
| 896 | func fetchRepoStars(client *api.Client, host string, skills []skillResult) map[int]int { |
| 897 | const maxWorkers = 10 |
| 898 | sem := make(chan struct{}, maxWorkers) |
| 899 | var wg sync.WaitGroup |
| 900 | var mu sync.Mutex |
| 901 | |
| 902 | repoStars := make(map[string]int) |
| 903 | seen := make(map[string]bool) |
| 904 | |
| 905 | for _, s := range skills { |
| 906 | if seen[s.Repo] { |
| 907 | continue |
| 908 | } |
| 909 | seen[s.Repo] = true |
| 910 | |
| 911 | wg.Add(1) |
| 912 | go func(owner, repo, fullName string) { |
| 913 | defer wg.Done() |
| 914 | sem <- struct{}{} |
| 915 | defer func() { <-sem }() |
| 916 | |
| 917 | apiPath := fmt.Sprintf("repos/%s/%s", owner, repo) |
| 918 | var info repoInfo |
| 919 | if err := client.REST(host, "GET", apiPath, nil, &info); err != nil { |
| 920 | return |
| 921 | } |
| 922 | mu.Lock() |
| 923 | repoStars[fullName] = info.StargazersCount |
| 924 | mu.Unlock() |
| 925 | }(s.Owner, s.RepoName, s.Repo) |
| 926 | } |
| 927 | wg.Wait() |
| 928 | |
| 929 | result := make(map[int]int, len(skills)) |
| 930 | for i, s := range skills { |
| 931 | if stars, ok := repoStars[s.Repo]; ok { |
| 932 | result[i] = stars |
| 933 | } |
| 934 | } |
| 935 | return result |
| 936 | } |
no test coverage detected