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