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