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